<!DOCTYPE html>
<html lang="zh-CN">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="robots" content="noodp" />
        <title>Java对象和多态 - L_B__</title><meta name="referrer" content="no-referrer">
<meta name="description" content="java面向对象"><meta property="og:title" content="Java对象和多态" />
<meta property="og:description" content="java面向对象" />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://acking-you.github.io/posts/java%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/" /><meta property="og:image" content="https://acking-you.github.io/logo.png"/><meta property="article:section" content="posts" />
<meta property="article:published_time" content="2022-01-23T00:00:00+00:00" />
<meta property="article:modified_time" content="2022-01-23T00:00:00+00:00" />

<meta name="twitter:card" content="summary_large_image"/>
<meta name="twitter:image" content="https://acking-you.github.io/logo.png"/>

<meta name="twitter:title" content="Java对象和多态"/>
<meta name="twitter:description" content="java面向对象"/>
<meta name="application-name" content="FeelIt">
<meta name="apple-mobile-web-app-title" content="FeelIt"><meta name="theme-color" content="#ffffff"><meta name="msapplication-TileColor" content="#da532c"><link rel="canonical" href="https://acking-you.github.io/posts/java%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/" /><link rel="prev" href="https://acking-you.github.io/posts/java%E5%BC%82%E5%B8%B8/" /><link rel="next" href="https://acking-you.github.io/posts/java%E5%A4%9A%E7%BA%BF%E7%A8%8B/" /><link rel="stylesheet" href="/css/page.min.css"><link rel="stylesheet" href="/css/home.min.css"><script type="application/ld+json">
    {
        "@context": "http://schema.org",
        "@type": "BlogPosting",
        "headline": "Java对象和多态",
        "inLanguage": "zh-CN",
        "mainEntityOfPage": {
            "@type": "WebPage",
            "@id": "https:\/\/acking-you.github.io\/posts\/java%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1\/"
        },"genre": "posts","keywords": "Java对象和多态","wordcount":  12519 ,
        "url": "https:\/\/acking-you.github.io\/posts\/java%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1\/","datePublished": "2022-01-23T00:00:00+00:00","dateModified": "2022-01-23T00:00:00+00:00","publisher": {
            "@type": "Organization",
            "name": "作者"},"author": {
                "@type": "Person",
                "name": "作者"
            },"description": "java面向对象"
    }
    </script></head><body data-header-desktop="auto" data-header-mobile="auto"><script>(window.localStorage && localStorage.getItem('theme') ? localStorage.getItem('theme') === 'dark' : ('auto' === 'auto' ? window.matchMedia('(prefers-color-scheme: dark)').matches : 'auto' === 'dark')) && document.body.setAttribute('theme', 'dark');</script>

        <div id="mask"></div><div class="wrapper"><header class="desktop" id="header-desktop">
    <div class="header-wrapper">
        <div class="header-title">
            <a href="/" title="L_B__">L_B__</a>
        </div>
        <div class="menu">
            <div class="menu-inner"><a class="menu-item" href="/posts/"> 文章 </a><a class="menu-item" href="/tags/"> 标签 </a><a class="menu-item" href="/categories/"> 分类 </a><span class="menu-item delimiter"></span><span class="menu-item search" id="search-desktop">
                        <input type="text" placeholder="搜索文章标题或内容..." id="search-input-desktop">
                        <a href="#" class="search-button search-toggle" id="search-toggle-desktop" title="搜索">
                            <i class="fas fa-search fa-fw"></i>
                        </a>
                        <a href="#" class="search-button search-clear" id="search-clear-desktop" title="清空">
                            <i class="fas fa-times-circle fa-fw"></i>
                        </a>
                        <span class="search-button search-loading" id="search-loading-desktop">
                            <i class="fas fa-spinner fa-fw fa-spin"></i>
                        </span>
                    </span><a href="javascript:void(0);" class="menu-item theme-switch" title="切换主题">
                    <i class="fas fa-adjust fa-fw"></i>
                </a>
            </div>
        </div>
    </div>
</header><header class="mobile" id="header-mobile">
    <div class="header-container">
        <div class="header-wrapper">
            <div class="header-title">
                <a href="/" title="L_B__">L_B__</a>
            </div>
            <div class="menu-toggle" id="menu-toggle-mobile">
                <span></span><span></span><span></span>
            </div>
        </div>
        <div class="menu" id="menu-mobile"><div class="search-wrapper">
                    <div class="search mobile" id="search-mobile">
                        <input type="text" placeholder="搜索文章标题或内容..." id="search-input-mobile">
                        <a href="#" class="search-button search-toggle" id="search-toggle-mobile" title="搜索">
                            <i class="fas fa-search fa-fw"></i>
                        </a>
                        <a href="#" class="search-button search-clear" id="search-clear-mobile" title="清空">
                            <i class="fas fa-times-circle fa-fw"></i>
                        </a>
                        <span class="search-button search-loading" id="search-loading-mobile">
                            <i class="fas fa-spinner fa-fw fa-spin"></i>
                        </span>
                    </div>
                    <a href="#" class="search-cancel" id="search-cancel-mobile">
                        取消
                    </a>
                </div><a class="menu-item" href="/posts/" title="">文章</a><a class="menu-item" href="/tags/" title="">标签</a><a class="menu-item" href="/categories/" title="">分类</a><div class="menu-item"><a href="javascript:void(0);" class="theme-switch" title="切换主题">
                    <i class="fas fa-adjust fa-fw"></i>
                </a>
            </div></div>
    </div>
</header><div class="search-dropdown desktop">
    <div id="search-dropdown-desktop"></div>
</div>
<div class="search-dropdown mobile">
    <div id="search-dropdown-mobile"></div>
</div><main class="main">
                <div class="container"><div class="toc" id="toc-auto">
            <h2 class="toc-title">目录</h2>
            <div class="toc-content" id="toc-content-auto"></div>
        </div><article class="page single" data-toc="disable"><div class="featured-image"><img
        class="lazyload"
        src="/svg/loading.min.svg"
        data-src="https://img-blog.csdnimg.cn/img_convert/8db816efd6abe83538c4d47108d9c840.png#pic_center"
        data-srcset="https://img-blog.csdnimg.cn/img_convert/8db816efd6abe83538c4d47108d9c840.png#pic_center, https://img-blog.csdnimg.cn/img_convert/8db816efd6abe83538c4d47108d9c840.png#pic_center 1.5x, https://img-blog.csdnimg.cn/img_convert/8db816efd6abe83538c4d47108d9c840.png#pic_center 2x"
        data-sizes="auto"
        alt="https://img-blog.csdnimg.cn/img_convert/8db816efd6abe83538c4d47108d9c840.png#pic_center"
        title="java面向对象" /></div><div class="single-card" data-image="true"><h2 class="single-title animated flipInX">Java对象和多态</h2><div class="post-meta">
                <div class="post-meta-line"><span class="post-author"><a href="/" title="Author" rel=" author" class="author"><i class="fas fa-user-circle fa-fw"></i>作者</a></span>&nbsp;<span class="post-category">出版于  <a href="/categories/javase%E7%AC%94%E8%AE%B0/"><i class="far fa-folder fa-fw"></i>JavaSE笔记</a></span></div>
                <div class="post-meta-line"><span><i class="far fa-calendar-alt fa-fw"></i>&nbsp;<time datetime="2022-01-23">2022-01-23</time></span>&nbsp;<span><i class="fas fa-pencil-alt fa-fw"></i>&nbsp;约 12519 字</span>&nbsp;
                    <span><i class="far fa-clock fa-fw"></i>&nbsp;预计阅读 25 分钟</span>&nbsp;</div>
            </div>
            
            <hr><div class="details toc" id="toc-static"  data-kept="">
                    <div class="details-summary toc-title">
                        <span>目录</span>
                        <span><i class="details-icon fas fa-angle-right"></i></span>
                    </div>
                    <div class="details-content toc-content" id="toc-content-static"><nav id="TableOfContents">
  <ul>
    <li><a href="#面向对象基础">面向对象基础</a></li>
    <li><a href="#类的基本结构">类的基本结构</a>
      <ul>
        <li><a href="#成员变量">成员变量</a></li>
        <li><a href="#成员方法">成员方法</a></li>
        <li><a href="#对象设计练习">对象设计练习</a></li>
        <li><a href="#方法的重载">方法的重载</a></li>
        <li><a href="#构造方法">构造方法</a></li>
        <li><a href="#静态变量和静态方法">静态变量和静态方法</a></li>
        <li><a href="#代码块和静态代码块">代码块和静态代码块</a></li>
        <li><a href="#string和stringbuilder类">String和StringBuilder类</a></li>
      </ul>
    </li>
    <li><a href="#包和访问控制">包和访问控制</a>
      <ul>
        <li><a href="#包声明和导入">包声明和导入</a></li>
        <li><a href="#静态导入">静态导入</a></li>
        <li><a href="#访问控制">访问控制</a></li>
      </ul>
    </li>
    <li><a href="#数组类型">数组类型</a>
      <ul>
        <li><a href="#一维数组">一维数组</a></li>
        <li><a href="#数组的遍历">数组的遍历</a></li>
        <li><a href="#二维数组">二维数组</a></li>
        <li><a href="#多维数组">多维数组</a></li>
        <li><a href="#可变长参数">可变长参数</a></li>
        <li><a href="#实战三大基本排序算法">实战：三大基本排序算法</a></li>
      </ul>
    </li>
    <li><a href="#封装继承和多态">封装、继承和多态</a>
      <ul>
        <li><a href="#封装">封装</a></li>
        <li><a href="#继承">继承</a></li>
        <li><a href="#多态">多态</a></li>
      </ul>
    </li>
    <li><a href="#内部类">内部类</a>
      <ul>
        <li><a href="#成员内部类">成员内部类</a></li>
        <li><a href="#静态内部类">静态内部类</a></li>
        <li><a href="#局部内部类">局部内部类</a></li>
        <li><a href="#匿名内部类">匿名内部类</a></li>
      </ul>
    </li>
    <li><a href="#枚举类">枚举类</a></li>
    <li><a href="#基本类型包装类">基本类型包装类</a>
      <ul>
        <li></li>
      </ul>
    </li>
    <li><a href="#面向对象编程实战">面向对象编程实战</a>
      <ul>
        <li><a href="#对象设计面向对象多态运用">对象设计（面向对象、多态运用）</a></li>
        <li><a href="#二分搜索搜索算法">二分搜索（搜索算法）</a></li>
        <li><a href="#快速排序排序算法递归分治">快速排序（排序算法、递归分治）</a></li>
        <li><a href="#01背包问题回溯法剪枝动态规划优化">0/1背包问题（回溯法、剪枝/动态规划优化）</a></li>
      </ul>
    </li>
  </ul>
</nav></div>
                </div><div class="content" id="content"><h1 id="java对象和多态-面向对象">Java对象和多态 （面向对象）</h1>
<p><a href="https://www.bilibili.com/video/BV1Gv411T7pi?p=18" target="_blank" rel="noopener noreffer">配套视频</a></p>
<h2 id="面向对象基础">面向对象基础</h2>
<p>面向对象程序设计(Object Oriented Programming)</p>
<p>对象基于类创建，类相当于一个模板，对象就是根据模板创建出来的实体（就像做月饼，我们要做一个月饼首先需要一个模具，模具就是我们的类，而做出来的月饼，就是类的实现，也叫做对象），类是抽象的数据类型，并不能代表某一个具体的事物，类是对象的一个模板。类具有自己的属性，包括成员变量、成员方法等，我们可以调用类的成员方法来让类进行一些操作。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="n">Scanner</span> <span class="n">sc</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Scanner</span><span class="o">(</span><span class="n">System</span><span class="o">.</span><span class="na">in</span><span class="o">);</span>
<span class="n">String</span> <span class="n">str</span> <span class="o">=</span> <span class="n">sc</span><span class="o">.</span><span class="na">nextLine</span><span class="o">();</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;你输入了：&#34;</span><span class="o">+</span><span class="n">str</span><span class="o">);</span>
<span class="n">sc</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
</code></pre></div><p>所有的对象，都需要通过<code>new</code>关键字创建，基本数据类型不是对象！Java不是纯面对对象语言！</p>
<p>不是基本类型的变量，都是引用类型，引用类型变量代表一个对象，而基本数据类型变量，保存的是基本数据类型的值，我们可以通过引用来对对象进行操作。（最好不要理解为引用指向对象的地址，初学者不要谈内存，学到JVM时再来讨论）</p>
<p>对象占用的内存由JVM统一管理，不需要手动释放内存，当一个对象不再使用时（比如失去引用或是离开了作用域）会被JVM自动清理，内存管理更方便！</p>
<hr>
<h2 id="类的基本结构">类的基本结构</h2>
<p>为了快速掌握，我们自己创建一个自己的类，创建的类文件名称应该和类名一致。</p>
<h3 id="成员变量">成员变量</h3>
<p>在类中，可以包含许多的成员变量，也叫成员属性，成员字段(field)通过<code>.</code>来访问我们类中的成员变量，我们可以通过类创建的对象来访问和修改这些变量。成员变量是属于对象的！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Test</span> <span class="o">{</span>
    <span class="kt">int</span> <span class="n">age</span><span class="o">;</span>
    <span class="n">String</span> <span class="n">name</span><span class="o">;</span>
<span class="o">}</span>

<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
    <span class="n">Test</span> <span class="n">test</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Test</span><span class="o">();</span>
    <span class="n">test</span><span class="o">.</span><span class="na">name</span> <span class="o">=</span> <span class="s">&#34;奥利给&#34;</span><span class="o">;</span>
    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">test</span><span class="o">.</span><span class="na">name</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div><p>成员变量默认带有初始值，也可以自己定义初始值。</p>
<h3 id="成员方法">成员方法</h3>
<p>我们之前的学习中接触过方法(Method)吗？主方法！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
  <span class="c1">//Body
</span><span class="c1"></span><span class="o">}</span>
</code></pre></div><p>方法是语句的集合，是为了完成某件事情而存在的。完成某件事情，可以有结果，也可以做了就做了，不返回结果。比如计算两个数字的和，我们需要得到计算后的结果，所以说方法需要有返回值；又比如，我们只想吧数字打印在控制台，只需要打印就行，不用给我结果，所以说方法不需要有返回值。</p>
<h4 id="方法的定义和使用">方法的定义和使用</h4>
<p>在类中，我们可以定义自己的方法，格式如下：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="o">[</span><span class="n">返回值类型</span><span class="o">]</span> <span class="nf">方法名称</span><span class="o">([</span><span class="n">参数</span><span class="o">]){</span>
  <span class="c1">//方法体
</span><span class="c1"></span>  <span class="k">return</span> <span class="n">结果</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div><ul>
<li>返回值类型：可以是引用类型和基本类型，还可以是void，表示没有返回值</li>
<li>方法名称：和标识符的规则一致，和变量一样，规范小写字母开头！</li>
<li>参数：例如方法需要计算两个数的和，那么我们就要把两个数到底是什么告诉方法，那么它们就可以作为参数传入方法</li>
<li>方法体：方法具体要干的事情</li>
<li>结果：方法执行的结果通过return返回（如果返回类型为void，可以省略return）</li>
</ul>
<p>非void方法中，<code>return</code>关键字不一定需要放在最后，但是一定要保证方法在任何情况下都具有返回值！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kt">int</span> <span class="nf">test</span><span class="o">(</span><span class="kt">int</span> <span class="n">a</span><span class="o">){</span>
  <span class="k">if</span><span class="o">(</span><span class="n">a</span> <span class="o">&gt;</span> <span class="n">0</span><span class="o">){</span>
    <span class="c1">//缺少retrun语句！
</span><span class="c1"></span>  <span class="o">}</span><span class="k">else</span><span class="o">{</span>
    <span class="k">return</span> <span class="n">0</span><span class="o">;</span>
  <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><p><code>return</code>也能用来提前结束整个方法，无论此时程序执行到何处，无论return位于哪里，都会立即结束个方法！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
   <span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">0</span><span class="o">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">10</span><span class="o">;</span> <span class="n">i</span><span class="o">++)</span> <span class="o">{</span>
       <span class="k">if</span><span class="o">(</span><span class="n">i</span> <span class="o">==</span> <span class="n">1</span><span class="o">)</span> <span class="k">return</span><span class="o">;</span>   <span class="c1">//在循环内返回了！和break区别？
</span><span class="c1"></span>   <span class="o">}</span>
   <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;淦&#34;</span><span class="o">);</span>   <span class="c1">//还会到这里吗？
</span><span class="c1"></span><span class="o">}</span>
</code></pre></div><p>传入方法的参数，如果是基本类型，会在调用方法的时候，对参数的值进行复制，方法中的参数变量，不是我们传入的变量本身！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
    <span class="kt">int</span> <span class="n">a</span> <span class="o">=</span> <span class="n">10</span><span class="o">,</span> <span class="n">b</span> <span class="o">=</span> <span class="n">20</span><span class="o">;</span>
  	<span class="k">new</span> <span class="n">Test</span><span class="o">().</span><span class="na">swap</span><span class="o">(</span><span class="n">a</span><span class="o">,</span> <span class="n">b</span><span class="o">);</span>
  	<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;a=&#34;</span><span class="o">+</span><span class="n">a</span><span class="o">+</span><span class="s">&#34;, b=&#34;</span><span class="o">+</span><span class="n">b</span><span class="o">);</span>
<span class="o">}</span>

<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Test</span><span class="o">{</span>
 	<span class="kt">void</span> <span class="nf">swap</span><span class="o">(</span><span class="kt">int</span> <span class="n">a</span><span class="o">,</span> <span class="kt">int</span> <span class="n">b</span><span class="o">){</span>  <span class="c1">//传递的仅仅是值而已！
</span><span class="c1"></span>  		<span class="kt">int</span> <span class="n">temp</span> <span class="o">=</span> <span class="n">a</span><span class="o">;</span>
  		<span class="n">a</span> <span class="o">=</span> <span class="n">b</span><span class="o">;</span>
 			<span class="n">b</span> <span class="o">=</span> <span class="n">temp</span><span class="o">;</span>
	<span class="o">}</span> 
<span class="o">}</span>
</code></pre></div><p>传入方法的参数，如果是引用类型，那么传入的依然是该对象的引用！（类似于C语言的指针）</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">B</span><span class="o">{</span>
 	<span class="n">String</span> <span class="n">name</span><span class="o">;</span>
<span class="o">}</span>

<span class="kd">public</span> <span class="kd">class</span> <span class="nc">A</span><span class="o">{</span>
 	<span class="kt">void</span> <span class="nf">test</span><span class="o">(</span><span class="n">B</span> <span class="n">b</span><span class="o">){</span>  <span class="c1">//传递的是对象的引用，而不是值
</span><span class="c1"></span>    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">b</span><span class="o">.</span><span class="na">name</span><span class="o">);</span>
  <span class="o">}</span>
<span class="o">}</span>

<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
    <span class="kt">int</span> <span class="n">a</span> <span class="o">=</span> <span class="n">10</span><span class="o">,</span> <span class="n">b</span> <span class="o">=</span> <span class="n">20</span><span class="o">;</span>
  	<span class="n">B</span> <span class="n">b</span> <span class="o">=</span> <span class="k">new</span> <span class="n">B</span><span class="o">();</span>
  	<span class="n">b</span><span class="o">.</span><span class="na">name</span> <span class="o">=</span> <span class="s">&#34;lbw&#34;</span><span class="o">;</span>
  	<span class="k">new</span> <span class="n">A</span><span class="o">().</span><span class="na">test</span><span class="o">(</span><span class="n">b</span><span class="o">);</span>
  	<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;a=&#34;</span><span class="o">+</span><span class="n">a</span><span class="o">+</span><span class="s">&#34;, b=&#34;</span><span class="o">+</span><span class="n">b</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div><p>方法之间可以相互调用</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kt">void</span> <span class="nf">a</span><span class="o">(){</span>
  <span class="c1">//xxxx
</span><span class="c1"></span><span class="o">}</span>

<span class="kt">void</span> <span class="nf">b</span><span class="o">(){</span>
  <span class="n">a</span><span class="o">();</span>
<span class="o">}</span>
</code></pre></div><p>当方法在自己内部调用自己时，称为递归调用（递归很危险，慎重！）</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kt">int</span> <span class="nf">a</span><span class="o">(){</span>
  <span class="k">return</span> <span class="n">a</span><span class="o">();</span>
<span class="o">}</span>
</code></pre></div><p>成员方法和成员变量一样，是属于对象的，只能通过对象去调用！</p>
<hr>
<h3 id="对象设计练习">对象设计练习</h3>
<ul>
<li>学生应该具有以下属性：名字、年龄</li>
<li>学生应该具有以下行为：学习、运动、说话</li>
</ul>
<hr>
<h3 id="方法的重载">方法的重载</h3>
<p>一个类中可以包含多个同名的方法，但是需要的形式参数不一样。（补充：形式参数就是定义方法需要的参数，实际参数就传入的参数）方法的返回类型，可以相同，也可以不同，但是仅返回类型不同，是不允许的！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Test</span> <span class="o">{</span>
    <span class="kt">int</span> <span class="nf">a</span><span class="o">(){</span>   <span class="c1">//原本的方法
</span><span class="c1"></span>       <span class="k">return</span> <span class="n">1</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kt">int</span> <span class="nf">a</span><span class="o">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">){</span>  <span class="c1">//ok，形参不同
</span><span class="c1"></span>        <span class="k">return</span> <span class="n">i</span><span class="o">;</span>
    <span class="o">}</span>
    
    <span class="kt">void</span> <span class="nf">a</span><span class="o">(</span><span class="kt">byte</span> <span class="n">i</span><span class="o">){</span>  <span class="c1">//ok，返回类型和形参都不同
</span><span class="c1"></span>        
    <span class="o">}</span>
    
    <span class="kt">void</span> <span class="nf">a</span><span class="o">(){</span>  <span class="c1">//错误，仅返回值类型名称不同不能重载
</span><span class="c1"></span>        
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><p>现在我们就可以使用不同的参数，但是支持调用同样的方法，执行一样的逻辑：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Test</span> <span class="o">{</span>
    <span class="kt">int</span> <span class="nf">sum</span><span class="o">(</span><span class="kt">int</span> <span class="n">a</span><span class="o">,</span> <span class="kt">int</span> <span class="n">b</span><span class="o">){</span>   <span class="c1">//只有int支持，不灵活！
</span><span class="c1"></span>        <span class="k">return</span> <span class="n">a</span><span class="o">+</span><span class="n">b</span><span class="o">;</span>
    <span class="o">}</span>
    
    <span class="kt">double</span> <span class="nf">sum</span><span class="o">(</span><span class="kt">double</span> <span class="n">a</span><span class="o">,</span> <span class="kt">double</span> <span class="n">b</span><span class="o">){</span>  <span class="c1">//重写一个double类型的，就支持小数计算了
</span><span class="c1"></span>        <span class="k">return</span> <span class="n">a</span><span class="o">+</span><span class="n">b</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><p>现在我们有很多种重写的方法，那么传入实参后，到底进了哪个方法呢？</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Test</span> <span class="o">{</span>
    <span class="kt">void</span> <span class="nf">a</span><span class="o">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">){</span>
        <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;调用了int&#34;</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="kt">void</span> <span class="nf">a</span><span class="o">(</span><span class="kt">short</span> <span class="n">i</span><span class="o">){</span>
        <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;调用了short&#34;</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="kt">void</span> <span class="nf">a</span><span class="o">(</span><span class="kt">long</span> <span class="n">i</span><span class="o">){</span>
        <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;调用了long&#34;</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="kt">void</span> <span class="nf">a</span><span class="o">(</span><span class="kt">char</span> <span class="n">i</span><span class="o">){</span>
        <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;调用了char&#34;</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="kt">void</span> <span class="nf">a</span><span class="o">(</span><span class="kt">double</span> <span class="n">i</span><span class="o">){</span>
        <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;调用了double&#34;</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="kt">void</span> <span class="nf">a</span><span class="o">(</span><span class="kt">float</span> <span class="n">i</span><span class="o">){</span>
        <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;调用了float&#34;</span><span class="o">);</span>
    <span class="o">}</span>
  
  	<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">Test</span> <span class="n">test</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Test</span><span class="o">();</span>
        <span class="n">test</span><span class="o">.</span><span class="na">a</span><span class="o">(</span><span class="n">1</span><span class="o">);</span>   <span class="c1">//直接输入整数
</span><span class="c1"></span>        <span class="n">test</span><span class="o">.</span><span class="na">a</span><span class="o">(</span><span class="n">1</span><span class="o">.</span><span class="na">0</span><span class="o">);</span>  <span class="c1">//直接输入小数
</span><span class="c1"></span>
        <span class="kt">short</span> <span class="n">s</span> <span class="o">=</span> <span class="n">2</span><span class="o">;</span>
        <span class="n">test</span><span class="o">.</span><span class="na">a</span><span class="o">(</span><span class="n">s</span><span class="o">);</span>  <span class="c1">//会对号入座吗？
</span><span class="c1"></span>        <span class="n">test</span><span class="o">.</span><span class="na">a</span><span class="o">(</span><span class="n">1</span><span class="o">.</span><span class="na">0F</span><span class="o">);</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><h3 id="构造方法">构造方法</h3>
<p>构造方法（构造器）没有返回值，也可以理解为，返回的是当前对象的引用！每一个类都默认自带一个无参构造方法。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="c1">//反编译结果
</span><span class="c1"></span><span class="kn">package</span> <span class="nn">com.test</span><span class="o">;</span>

<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Test</span> <span class="o">{</span>
    <span class="kd">public</span> <span class="nf">Test</span><span class="o">()</span> <span class="o">{</span>    <span class="c1">//即使你什么都不编写，也自带一个无参构造方法，只是默认是隐藏的
</span><span class="c1"></span>    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><p>反编译其实就是把我们编译好的class文件变回Java源代码。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="n">Test</span> <span class="n">test</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Test</span><span class="o">();</span>  <span class="c1">//实际上存在Test()这个的方法，new关键字就是用来创建并得到引用的
</span><span class="c1">// new + 你想要使用的构造方法
</span></code></pre></div><p>这种方法没有写明返回值，但是每个类都必须具有这个方法！只有调用类的构造方法，才能创建类的对象！</p>
<p>类要在一开始准备的所有东西，都会在构造方法里面执行，完成构造方法的内容后，才能创建出对象！</p>
<p>一般最常用的就是给成员属性赋初始值：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Student</span> <span class="o">{</span>
    <span class="n">String</span> <span class="n">name</span><span class="o">;</span>
    
    <span class="n">Student</span><span class="o">(){</span>
        <span class="n">name</span> <span class="o">=</span> <span class="s">&#34;伞兵一号&#34;</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><p>我们可以手动指定有参构造，当遇到名称冲突时，需要用到this关键字</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Student</span> <span class="o">{</span>
    <span class="n">String</span> <span class="n">name</span><span class="o">;</span>

    <span class="n">Student</span><span class="o">(</span><span class="n">String</span> <span class="n">name</span><span class="o">){</span>   <span class="c1">//形参和类成员变量冲突了，Java会优先使用形式参数定义的变量！
</span><span class="c1"></span>        <span class="k">this</span><span class="o">.</span><span class="na">name</span> <span class="o">=</span> <span class="n">name</span><span class="o">;</span>  <span class="c1">//通过this指代当前的对象属性，this就代表当前对象
</span><span class="c1"></span>    <span class="o">}</span>
<span class="o">}</span>

<span class="c1">//idea 右键快速生成！
</span></code></pre></div><p>注意，this只能用于指代当前对象的内容，因此，只有属于对象拥有的部分才可以使用this，也就是说，只能在类的成员方法中使用this，不能在静态方法中使用this关键字。</p>
<p>在我们定义了新的有参构造之后，默认的无参构造会被覆盖！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="c1">//反编译后依然只有我们定义的有参构造！
</span></code></pre></div><p>如果同时需要有参和无参构造，那么就需要用到方法的重载！手动再去定义一个无参构造。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Student</span> <span class="o">{</span>
    <span class="n">String</span> <span class="n">name</span><span class="o">;</span>

    <span class="n">Student</span><span class="o">(){</span>

    <span class="o">}</span>

    <span class="n">Student</span><span class="o">(</span><span class="n">String</span> <span class="n">name</span><span class="o">){</span>
        <span class="k">this</span><span class="o">.</span><span class="na">name</span> <span class="o">=</span> <span class="n">name</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><p>成员变量的初始化始终在构造方法执行之前</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Student</span> <span class="o">{</span>
    <span class="n">String</span> <span class="n">a</span> <span class="o">=</span> <span class="s">&#34;sadasa&#34;</span><span class="o">;</span>

    <span class="n">Student</span><span class="o">(){</span>
        <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">a</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">Student</span> <span class="n">s</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Student</span><span class="o">();</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><h3 id="静态变量和静态方法">静态变量和静态方法</h3>
<p>静态变量和静态方法是类具有的属性（后面还会提到静态类、静态代码块），也可以理解为是所有对象共享的内容。我们通过使用<code>static</code>关键字来声明一个变量或一个方法为静态的，一旦被声明为静态，那么通过这个类创建的所有对象，操作的都是同一个目标，也就是说，对象再多，也只有这一个静态的变量或方法。那么，一个对象改变了静态变量的值，那么其他的对象读取的就是被改变的值。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Student</span> <span class="o">{</span>
    <span class="kd">static</span> <span class="kt">int</span> <span class="n">a</span><span class="o">;</span>
<span class="o">}</span>

<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
	<span class="n">Student</span> <span class="n">s1</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Student</span><span class="o">();</span>
	<span class="n">s1</span><span class="o">.</span><span class="na">a</span> <span class="o">=</span> <span class="n">10</span><span class="o">;</span>
	<span class="n">Student</span> <span class="n">s2</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Student</span><span class="o">();</span>
	<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">s2</span><span class="o">.</span><span class="na">a</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div><p>不推荐使用对象来调用，被标记为静态的内容，可以直接通过<code>类名.xxx</code>的形式访问</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
   <span class="n">Student</span><span class="o">.</span><span class="na">a</span> <span class="o">=</span> <span class="n">10</span><span class="o">;</span>
   <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">Student</span><span class="o">.</span><span class="na">a</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div><h4 id="简述类加载机制">简述类加载机制</h4>
<p>类并不是在一开始就全部加载好，而是在需要时才会去加载（提升速度）以下情况会加载类：</p>
<ul>
<li>访问类的静态变量，或者为静态变量赋值</li>
<li>new 创建类的实例（隐式加载）</li>
<li>调用类的静态方法</li>
<li>子类初始化时</li>
<li>其他的情况会在讲到反射时介绍</li>
</ul>
<p>所有被标记为静态的内容，会在类刚加载的时候就分配，而不是在对象创建的时候分配，所以说静态内容一定会在第一个对象初始化之前完成加载。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Student</span> <span class="o">{</span>
    <span class="kd">static</span> <span class="kt">int</span> <span class="n">a</span> <span class="o">=</span> <span class="n">test</span><span class="o">();</span>  <span class="c1">//直接调用静态方法，只能调用静态方法
</span><span class="c1"></span>
    <span class="n">Student</span><span class="o">(){</span>
        <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;构造类对象&#34;</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="kd">static</span> <span class="kt">int</span> <span class="nf">test</span><span class="o">(){</span>   <span class="c1">//静态方法刚加载时就有了
</span><span class="c1"></span>        <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;初始化变量a&#34;</span><span class="o">);</span>
        <span class="k">return</span> <span class="n">1</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><p>思考：下面这种情况下，程序能正常运行吗？如果能，会输出什么内容？</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Student</span> <span class="o">{</span>
    <span class="kd">static</span> <span class="kt">int</span> <span class="n">a</span> <span class="o">=</span> <span class="n">test</span><span class="o">();</span>

    <span class="kd">static</span> <span class="kt">int</span> <span class="nf">test</span><span class="o">(){</span>
        <span class="k">return</span> <span class="n">a</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">Student</span><span class="o">.</span><span class="na">a</span><span class="o">);</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><p>定义和赋值是两个阶段，在定义时会使用默认值（上面讲的，类的成员变量会有默认值）定义出来之后，如果发现有赋值语句，再进行赋值，而这时，调用了静态方法，所以说会先去加载静态方法，静态方法调用时拿到a，而a这时仅仅是刚定义，所以说还是初始值，最后得到0</p>
<h3 id="代码块和静态代码块">代码块和静态代码块</h3>
<p>代码块在对象创建时执行，也是属于类的内容，但是它在构造方法执行之前执行（和成员变量初始值一样），且每创建一个对象时，只执行一次！（相当于构造之前的准备工作）</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Student</span> <span class="o">{</span>
    <span class="o">{</span>
        <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;我是代码块&#34;</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="n">Student</span><span class="o">(){</span>
        <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;我是构造方法&#34;</span><span class="o">);</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><p>静态代码块和上面的静态方法和静态变量一样，在类刚加载时就会调用；</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Student</span> <span class="o">{</span>
    <span class="kd">static</span> <span class="kt">int</span> <span class="n">a</span><span class="o">;</span>

    <span class="kd">static</span> <span class="o">{</span>
        <span class="n">a</span> <span class="o">=</span> <span class="n">10</span><span class="o">;</span>
    <span class="o">}</span>
    
    <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">Student</span><span class="o">.</span><span class="na">a</span><span class="o">);</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><h3 id="string和stringbuilder类">String和StringBuilder类</h3>
<p>字符串类是一个比较特殊的类，他是Java中唯一重载运算符的类！(Java不支持运算符重载，String是特例)</p>
<p>String的对象直接支持使用<code>+</code>或<code>+=</code>运算符来进行拼接，并形成新的String对象！（String的字符串是不可变的！）</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="n">String</span> <span class="n">a</span> <span class="o">=</span> <span class="s">&#34;dasdsa&#34;</span><span class="o">,</span> <span class="n">b</span> <span class="o">=</span> <span class="s">&#34;dasdasdsa&#34;</span><span class="o">;</span>
<span class="n">String</span> <span class="n">l</span> <span class="o">=</span> <span class="n">a</span><span class="o">+</span><span class="n">b</span><span class="o">;</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">l</span><span class="o">);</span>
</code></pre></div><p>大量进行字符串的拼接似乎不太好，编译器是很聪明的，String的拼接有可能会被编译器优化为StringBuilder来减少对象创建（对象频繁创建时很费时间同时占内存的！）</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="n">String</span> <span class="n">result</span><span class="o">=</span><span class="s">&#34;String&#34;</span><span class="o">+</span><span class="s">&#34;and&#34;</span><span class="o">;</span> <span class="c1">//会被优化成一句！
</span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="n">String</span> <span class="n">str1</span><span class="o">=</span><span class="s">&#34;String&#34;</span><span class="o">;</span>
<span class="n">String</span> <span class="n">str2</span><span class="o">=</span><span class="s">&#34;and&#34;</span><span class="o">;</span>
<span class="n">String</span> <span class="n">result</span><span class="o">=</span><span class="n">str1</span><span class="o">+</span><span class="n">str2</span><span class="o">;</span>
<span class="c1">//变量随时可变，在编译时无法确定result的值，那么只能在运行时再去确定
</span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="n">String</span> <span class="n">str1</span><span class="o">=</span><span class="s">&#34;String&#34;</span><span class="o">;</span>
<span class="n">String</span> <span class="n">str2</span><span class="o">=</span><span class="s">&#34;and&#34;</span><span class="o">;</span>
<span class="n">String</span> <span class="n">result</span><span class="o">=(</span><span class="k">new</span> <span class="n">StringBuilder</span><span class="o">(</span><span class="n">String</span><span class="o">.</span><span class="na">valueOf</span><span class="o">(</span><span class="n">str1</span><span class="o">))).</span><span class="na">append</span><span class="o">(</span><span class="n">str2</span><span class="o">).</span><span class="na">toString</span><span class="o">();</span>
<span class="c1">//使用StringBuilder，会采用类似于第一种实现，显然会更快！
</span></code></pre></div><p>StringBuilder也是一个类，但是它能够存储可变长度的字符串！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="n">StringBuilder</span> <span class="n">builder</span> <span class="o">=</span> <span class="k">new</span> <span class="n">StringBuilder</span><span class="o">();</span>
<span class="n">builder</span>
       <span class="o">.</span><span class="na">append</span><span class="o">(</span><span class="s">&#34;a&#34;</span><span class="o">)</span>
       <span class="o">.</span><span class="na">append</span><span class="o">(</span><span class="s">&#34;bc&#34;</span><span class="o">)</span>
       <span class="o">.</span><span class="na">append</span><span class="o">(</span><span class="s">&#34;d&#34;</span><span class="o">);</span>   <span class="c1">//链式调用
</span><span class="c1"></span><span class="n">String</span> <span class="n">str</span> <span class="o">=</span> <span class="n">builder</span><span class="o">.</span><span class="na">toString</span><span class="o">();</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">str</span><span class="o">);</span>
</code></pre></div><hr>
<h2 id="包和访问控制">包和访问控制</h2>
<h3 id="包声明和导入">包声明和导入</h3>
<p>包其实就是用来区分类位置的东西，也可以用来将我们的类进行分类，类似于C++中的namespace！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kn">package</span> <span class="nn">com.test</span><span class="o">;</span>

<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Test</span><span class="o">{</span>
  
<span class="o">}</span>
</code></pre></div><p>包其实是文件夹，比如com.test就是一个com文件夹中包含一个test文件夹，再包含我们Test类。</p>
<p>一般包按照个人或是公司域名的规则倒过来写 <code>顶级域名.一级域名.二级域名</code> <code>com.java.xxxx</code></p>
<p>如果需要使用其他包里面的类，那么我们需要<code>import</code>（类似于C/C++中的include）</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kn">import</span> <span class="nn">com.test.Student</span><span class="o">;</span>
</code></pre></div><p>也可以导入包下的全部（一般导入会由编译器自带帮我们补全，但是一定要记得我们需要导包！）</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kn">import</span> <span class="nn">com.test.*</span>
</code></pre></div><p>Java默认为我们导入了以下的包，不需要去声明</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kn">import</span> <span class="nn">java.lang.*</span>
</code></pre></div><h3 id="静态导入">静态导入</h3>
<p>静态导入可以直接导入某个类的静态方法或者是静态变量，导入后，相当于这个方法或是类在定义在当前类中，可以直接调用该方法。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kn">import static</span> <span class="nn">com.test.ui.Student.test</span><span class="o">;</span>

<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Main</span> <span class="o">{</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">test</span><span class="o">();</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><p>静态导入不会进行类的初始化！</p>
<h3 id="访问控制">访问控制</h3>
<p>Java支持对类属性访问的保护，也就是说，不希望外部类访问类中的属性或是方法，只允许内部调用，这种情况下我们就需要用到权限控制符。</p>
<p>![image-20210819160939950](C:/Users/Alone/Users/nagocoler/Library/Application Support/typora-user-images/image-20210819160939950.png)</p>
<p>权限控制符可以声明在方法、成员变量、类前面，一旦声明private，只能类内部访问！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Student</span> <span class="o">{</span>
    <span class="kd">private</span> <span class="kt">int</span> <span class="n">a</span> <span class="o">=</span> <span class="n">10</span><span class="o">;</span>   <span class="c1">//具有私有访问权限，只能类内部访问
</span><span class="c1"></span><span class="o">}</span>

<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
    <span class="n">Student</span> <span class="n">s</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Student</span><span class="o">();</span>
    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">s</span><span class="o">.</span><span class="na">a</span><span class="o">);</span>  <span class="c1">//还可以访问吗？
</span><span class="c1"></span><span class="o">}</span>
</code></pre></div><p>和文件名称相同的类，只能是public，并且一个java文件中只能有一个public class！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="c1">// Student.java
</span><span class="c1"></span><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Student</span> <span class="o">{</span>
    
<span class="o">}</span>
<span class="kd">class</span> <span class="nc">Test</span><span class="o">{</span>   <span class="c1">//不能添加权限修饰符！只能是default
</span><span class="c1"></span>	
<span class="o">}</span>
</code></pre></div><hr>
<h2 id="数组类型">数组类型</h2>
<p>假设出现一种情况，我想记录100个数字，定义100个变量还可行吗？</p>
<p><img
        class="lazyload"
        src="/svg/loading.min.svg"
        data-src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimgs.itxueyuan.com%2FCgq2xl329g-Adz0uAACwgSFkMho326.png&amp;refer=http%3A%2F%2Fimgs.itxueyuan.com&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=jpeg?sec=1632192902&amp;t=7a6d67fc01d0e3ea7816adf951c49605"
        data-srcset="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimgs.itxueyuan.com%2FCgq2xl329g-Adz0uAACwgSFkMho326.png&amp;refer=http%3A%2F%2Fimgs.itxueyuan.com&amp;app=2002&amp;size=f9999%2c10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=jpeg?sec=1632192902&amp;t=7a6d67fc01d0e3ea7816adf951c49605, https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimgs.itxueyuan.com%2FCgq2xl329g-Adz0uAACwgSFkMho326.png&amp;refer=http%3A%2F%2Fimgs.itxueyuan.com&amp;app=2002&amp;size=f9999%2c10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=jpeg?sec=1632192902&amp;t=7a6d67fc01d0e3ea7816adf951c49605 1.5x, https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimgs.itxueyuan.com%2FCgq2xl329g-Adz0uAACwgSFkMho326.png&amp;refer=http%3A%2F%2Fimgs.itxueyuan.com&amp;app=2002&amp;size=f9999%2c10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=jpeg?sec=1632192902&amp;t=7a6d67fc01d0e3ea7816adf951c49605 2x"
        data-sizes="auto"
        alt="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimgs.itxueyuan.com%2FCgq2xl329g-Adz0uAACwgSFkMho326.png&amp;refer=http%3A%2F%2Fimgs.itxueyuan.com&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=jpeg?sec=1632192902&amp;t=7a6d67fc01d0e3ea7816adf951c49605"
        title="img" /></p>
<p>我们可以使用到数组，数组是相同类型数据的有序集合。数组可以代表任何相同类型的一组内容（包括引用类型和基本类型）其中存放的每一个数据称为数组的一个元素，数组的下标是从0开始，也就是第一个元素的索引是0！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">int</span><span class="o">[</span><span class="n">10</span><span class="o">];</span>  <span class="c1">//需要new关键字来创建！
</span><span class="c1"></span><span class="n">String</span><span class="o">[]</span> <span class="n">arr2</span> <span class="o">=</span> <span class="k">new</span> <span class="n">String</span><span class="o">[</span><span class="n">10</span><span class="o">];</span>
</code></pre></div><p>数组本身也是类（编程不可见，C++写的），不是基本数据类型！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">int</span><span class="o">[</span><span class="n">10</span><span class="o">];</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">arr</span><span class="o">.</span><span class="na">length</span><span class="o">);</span>   <span class="c1">//数组有成员变量！
</span><span class="c1"></span><span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">arr</span><span class="o">.</span><span class="na">toString</span><span class="o">());</span>   <span class="c1">//数组有成员方法！
</span></code></pre></div><h3 id="一维数组">一维数组</h3>
<p>一维数组中，元素是依次排列的（线性），每个数组元素可以通过下标来访问！声明格式如下：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="n">类型</span><span class="o">[]</span> <span class="n">变量名称</span> <span class="o">=</span> <span class="k">new</span> <span class="n">类型</span><span class="o">[</span><span class="n">数组大小</span><span class="o">];</span>
<span class="n">类型</span> <span class="n">变量名称n</span> <span class="o">=</span> <span class="k">new</span> <span class="n">类型</span><span class="o">[</span><span class="n">数组大小</span><span class="o">];</span>  <span class="c1">//支持C语言样式，但不推荐！
</span><span class="c1"></span>
<span class="n">类型</span><span class="o">[]</span> <span class="n">变量名称</span> <span class="o">=</span> <span class="k">new</span> <span class="n">类型</span><span class="o">[]{...};</span>  <span class="c1">//静态初始化（直接指定值和大小）
</span><span class="c1"></span><span class="n">类型</span><span class="o">[]</span> <span class="n">变量名称</span> <span class="o">=</span> <span class="o">{...};</span>   <span class="c1">//同上，但是只能在定义时赋值
</span></code></pre></div><p>创建出来的数组每个元素都有默认值（规则和类的成员变量一样，C语言创建的数组需要手动设置默认值），我们可以通过下标去访问：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">int</span><span class="o">[</span><span class="n">10</span><span class="o">];</span>
<span class="n">arr</span><span class="o">[</span><span class="n">0</span><span class="o">]</span> <span class="o">=</span> <span class="n">626</span><span class="o">;</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">arr</span><span class="o">[</span><span class="n">0</span><span class="o">]);</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">arr</span><span class="o">[</span><span class="n">1</span><span class="o">]);</span>
</code></pre></div><p>我们可以通过<code>数组变量名称.length</code>来获取当前数组长度：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">int</span><span class="o">[]{</span><span class="n">1</span><span class="o">,</span> <span class="n">2</span><span class="o">,</span> <span class="n">3</span><span class="o">};</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">arr</span><span class="o">.</span><span class="na">length</span><span class="o">);</span>  <span class="c1">//打印length成员变量的值
</span></code></pre></div><p>数组在创建时，就固定长度，不可更改！访问超出数组长度的内容，会出现错误！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="n">String</span><span class="o">[]</span> <span class="n">arr</span> <span class="o">=</span> <span class="k">new</span> <span class="n">String</span><span class="o">[</span><span class="n">10</span><span class="o">];</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">arr</span><span class="o">[</span><span class="n">10</span><span class="o">]);</span>  <span class="c1">//出现异常！
</span><span class="c1"></span>
<span class="c1">//Exception in thread &#34;main&#34; java.lang.ArrayIndexOutOfBoundsException: 11
</span><span class="c1">//	at com.test.Application.main(Application.java:7)
</span></code></pre></div><p>思考：能不能直接修改length的值来实现动态扩容呢？</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">int</span><span class="o">[]{</span><span class="n">1</span><span class="o">,</span> <span class="n">2</span><span class="o">,</span> <span class="n">3</span><span class="o">};</span>
<span class="n">arr</span><span class="o">.</span><span class="na">length</span> <span class="o">=</span> <span class="n">10</span><span class="o">;</span>
</code></pre></div><p>数组做实参，因为数组也是类，所以形参得到的是数组的引用而不是复制的数组，操作的依然是数组对象本身</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
    <span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">int</span><span class="o">[]{</span><span class="n">1</span><span class="o">,</span> <span class="n">2</span><span class="o">,</span> <span class="n">3</span><span class="o">};</span>
    <span class="n">test</span><span class="o">(</span><span class="n">arr</span><span class="o">);</span>
    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">arr</span><span class="o">[</span><span class="n">0</span><span class="o">]);</span>
<span class="o">}</span>

<span class="kd">private</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">test</span><span class="o">(</span><span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span><span class="o">){</span>
    <span class="n">arr</span><span class="o">[</span><span class="n">0</span><span class="o">]</span> <span class="o">=</span> <span class="n">2934</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div><h3 id="数组的遍历">数组的遍历</h3>
<p>如果我们想要快速打印数组中的每一个元素，又怎么办呢？</p>
<h4 id="传统for循环">传统for循环</h4>
<p>我们很容易就联想到for循环</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">int</span><span class="o">[]{</span><span class="n">1</span><span class="o">,</span> <span class="n">2</span><span class="o">,</span> <span class="n">3</span><span class="o">};</span>
<span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">0</span><span class="o">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">arr</span><span class="o">.</span><span class="na">length</span><span class="o">;</span> <span class="n">i</span><span class="o">++)</span> <span class="o">{</span>
   <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">arr</span><span class="o">[</span><span class="n">i</span><span class="o">]);</span>
<span class="o">}</span>
</code></pre></div><h4 id="foreach">foreach</h4>
<p>传统for循环虽然可控性高，但是不够省事，要写一大堆东西，有没有一种省事的写法呢？</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">int</span><span class="o">[]{</span><span class="n">1</span><span class="o">,</span> <span class="n">2</span><span class="o">,</span> <span class="n">3</span><span class="o">};</span>
<span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">:</span> <span class="n">arr</span><span class="o">)</span> <span class="o">{</span>
    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">i</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div><p>foreach属于增强型的for循环，它使得代码更简洁，同时我们能直接拿到数组中的每一个数字。</p>
<h3 id="二维数组">二维数组</h3>
<p>二维数组其实就是存放数组的数组，每一个元素都存放一个数组的引用，也就相当于变成了一个平面。</p>
<p><img
        class="lazyload"
        src="/svg/loading.min.svg"
        data-src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Ffile.elecfans.com%2Fweb1%2FM00%2FDD%2F01%2Fo4YBAGASjymAK8QIAADiOdWkSVA342.jpg&amp;refer=http%3A%2F%2Ffile.elecfans.com&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=jpeg?sec=1632204192&amp;t=52381354d190d09899776f9bb868ef3e"
        data-srcset="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Ffile.elecfans.com%2Fweb1%2FM00%2FDD%2F01%2Fo4YBAGASjymAK8QIAADiOdWkSVA342.jpg&amp;refer=http%3A%2F%2Ffile.elecfans.com&amp;app=2002&amp;size=f9999%2c10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=jpeg?sec=1632204192&amp;t=52381354d190d09899776f9bb868ef3e, https://gimg2.baidu.com/image_search/src=http%3A%2F%2Ffile.elecfans.com%2Fweb1%2FM00%2FDD%2F01%2Fo4YBAGASjymAK8QIAADiOdWkSVA342.jpg&amp;refer=http%3A%2F%2Ffile.elecfans.com&amp;app=2002&amp;size=f9999%2c10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=jpeg?sec=1632204192&amp;t=52381354d190d09899776f9bb868ef3e 1.5x, https://gimg2.baidu.com/image_search/src=http%3A%2F%2Ffile.elecfans.com%2Fweb1%2FM00%2FDD%2F01%2Fo4YBAGASjymAK8QIAADiOdWkSVA342.jpg&amp;refer=http%3A%2F%2Ffile.elecfans.com&amp;app=2002&amp;size=f9999%2c10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=jpeg?sec=1632204192&amp;t=52381354d190d09899776f9bb868ef3e 2x"
        data-sizes="auto"
        alt="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Ffile.elecfans.com%2Fweb1%2FM00%2FDD%2F01%2Fo4YBAGASjymAK8QIAADiOdWkSVA342.jpg&amp;refer=http%3A%2F%2Ffile.elecfans.com&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=jpeg?sec=1632204192&amp;t=52381354d190d09899776f9bb868ef3e"
        title="img" /></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="c1">//三行两列
</span><span class="c1"></span><span class="kt">int</span><span class="o">[][]</span> <span class="n">arr</span> <span class="o">=</span> <span class="o">{</span> <span class="o">{</span><span class="n">1</span><span class="o">,</span> <span class="n">2</span><span class="o">},</span>
                <span class="o">{</span><span class="n">3</span><span class="o">,</span> <span class="n">4</span><span class="o">},</span>
                <span class="o">{</span><span class="n">5</span><span class="o">,</span> <span class="n">6</span><span class="o">}};</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">arr</span><span class="o">[</span><span class="n">2</span><span class="o">][</span><span class="n">1</span><span class="o">]);</span>
</code></pre></div><p>二维数组的遍历同一维数组一样，只不过需要嵌套循环！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kt">int</span><span class="o">[][]</span> <span class="n">arr</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">int</span><span class="o">[][]{</span> <span class="o">{</span><span class="n">1</span><span class="o">,</span> <span class="n">2</span><span class="o">},</span>
                           <span class="o">{</span><span class="n">3</span><span class="o">,</span> <span class="n">4</span><span class="o">},</span>
                           <span class="o">{</span><span class="n">5</span><span class="o">,</span> <span class="n">6</span><span class="o">}};</span>
<span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">0</span><span class="o">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">3</span><span class="o">;</span> <span class="n">i</span><span class="o">++)</span> <span class="o">{</span>
     <span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">j</span> <span class="o">=</span> <span class="n">0</span><span class="o">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="n">2</span><span class="o">;</span> <span class="n">j</span><span class="o">++)</span> <span class="o">{</span>
          <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">arr</span><span class="o">[</span><span class="n">i</span><span class="o">][</span><span class="n">j</span><span class="o">]);</span>
     <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><h3 id="多维数组">多维数组</h3>
<p>不止二维数组，还存在三维数组，也就是存放数组的数组的数组，原理同二维数组一样，逐级访问即可。</p>
<h3 id="可变长参数">可变长参数</h3>
<p>可变长参数其实就是数组的一种应用，我们可以指定方法的形参为一个可变长参数，要求实参可以根据情况动态填入0个或多个，而不是固定的数量</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
     <span class="n">test</span><span class="o">(</span><span class="s">&#34;AAA&#34;</span><span class="o">,</span> <span class="s">&#34;BBB&#34;</span><span class="o">,</span> <span class="s">&#34;CCC&#34;</span><span class="o">);</span>    <span class="c1">//可变长，最后都会被自动封装成一个数组
</span><span class="c1"></span><span class="o">}</span>
    
<span class="kd">private</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">test</span><span class="o">(</span><span class="n">String</span><span class="o">...</span> <span class="n">test</span><span class="o">){</span>
     <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">test</span><span class="o">[</span><span class="n">0</span><span class="o">]);</span>    <span class="c1">//其实参数就是一个数组
</span><span class="c1"></span><span class="o">}</span>
</code></pre></div><p>由于是数组，所以说只能使用一种类型的可变长参数，并且可变长参数只能放在最后一位！</p>
<h3 id="实战三大基本排序算法">实战：三大基本排序算法</h3>
<p>现在我们有一个数组，但是数组里面的数据是乱序排列的，如何使它变得有序？</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span> <span class="o">=</span> <span class="o">{</span><span class="n">8</span><span class="o">,</span> <span class="n">5</span><span class="o">,</span> <span class="n">0</span><span class="o">,</span> <span class="n">1</span><span class="o">,</span> <span class="n">4</span><span class="o">,</span> <span class="n">9</span><span class="o">,</span> <span class="n">2</span><span class="o">,</span> <span class="n">3</span><span class="o">,</span> <span class="n">6</span><span class="o">,</span> <span class="n">7</span><span class="o">};</span>
</code></pre></div><p>排序是编程的一个重要技能，掌握排序算法，你的技术才能更上一层楼，很多的项目都需要用到排序！三大排序算法：</p>
<ul>
<li>冒泡排序</li>
</ul>
<p>冒泡排序就是冒泡，其实就是不断使得我们无序数组中的最大数向前移动，经历n轮循环逐渐将每一个数推向最前。</p>
<ul>
<li>插入排序</li>
</ul>
<p>插入排序其实就跟我们打牌是一样的，我们在摸牌的时候，牌堆是乱序的，但是我们一张一张摸到手中进行排序，使得它变成了有序的！</p>
<p><img
        class="lazyload"
        src="/svg/loading.min.svg"
        data-src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg1.jjhgame.com%2Fstatic_data%2Fnewshelp%2F113_5c08e82d2ac8b.jpg&amp;refer=http%3A%2F%2Fimg1.jjhgame.com&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=jpeg?sec=1632208529&amp;t=f3fb9be4dce91c6364f5ec4f9faafc94"
        data-srcset="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg1.jjhgame.com%2Fstatic_data%2Fnewshelp%2F113_5c08e82d2ac8b.jpg&amp;refer=http%3A%2F%2Fimg1.jjhgame.com&amp;app=2002&amp;size=f9999%2c10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=jpeg?sec=1632208529&amp;t=f3fb9be4dce91c6364f5ec4f9faafc94, https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg1.jjhgame.com%2Fstatic_data%2Fnewshelp%2F113_5c08e82d2ac8b.jpg&amp;refer=http%3A%2F%2Fimg1.jjhgame.com&amp;app=2002&amp;size=f9999%2c10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=jpeg?sec=1632208529&amp;t=f3fb9be4dce91c6364f5ec4f9faafc94 1.5x, https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg1.jjhgame.com%2Fstatic_data%2Fnewshelp%2F113_5c08e82d2ac8b.jpg&amp;refer=http%3A%2F%2Fimg1.jjhgame.com&amp;app=2002&amp;size=f9999%2c10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=jpeg?sec=1632208529&amp;t=f3fb9be4dce91c6364f5ec4f9faafc94 2x"
        data-sizes="auto"
        alt="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg1.jjhgame.com%2Fstatic_data%2Fnewshelp%2F113_5c08e82d2ac8b.jpg&amp;refer=http%3A%2F%2Fimg1.jjhgame.com&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=jpeg?sec=1632208529&amp;t=f3fb9be4dce91c6364f5ec4f9faafc94"
        title="img" /></p>
<ul>
<li>选择排序</li>
</ul>
<p>选择排序其实就是每次都选择当前数组中最大的数排到最前面！</p>
<hr>
<h2 id="封装继承和多态">封装、继承和多态</h2>
<p>封装、继承和多态是面向对象编程的三大特性。</p>
<h3 id="封装">封装</h3>
<p>封装的目的是为了保证变量的安全性，使用者不必在意具体实现细节，而只是通过外部接口即可访问类的成员，如果不进行封装，类中的实例变量可以直接查看和修改，可能给整个代码带来不好的影响，因此在编写类时一般将成员变量私有化，外部类需要同getter和setter方法来查看和设置变量。</p>
<p>设想：学生小明已经创建成功，正常情况下能随便改他的名字和年龄吗？</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Student</span> <span class="o">{</span>
    <span class="kd">private</span> <span class="n">String</span> <span class="n">name</span><span class="o">;</span>
    <span class="kd">private</span> <span class="kt">int</span> <span class="n">age</span><span class="o">;</span>
  
    <span class="kd">public</span> <span class="nf">Student</span><span class="o">(</span><span class="n">String</span> <span class="n">name</span><span class="o">,</span> <span class="kt">int</span> <span class="n">age</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">name</span> <span class="o">=</span> <span class="n">name</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">age</span> <span class="o">=</span> <span class="n">age</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kt">int</span> <span class="nf">getAge</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">age</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="n">String</span> <span class="nf">getName</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">name</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><p>也就是说，外部现在只能通过调用我定义的方法来获取成员属性，而我们可以在这个方法中进行一些额外的操作，比如小明可以修改名字，但是名字中不能包含&quot;小&quot;这个字。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kt">void</span> <span class="nf">setName</span><span class="o">(</span><span class="n">String</span> <span class="n">name</span><span class="o">)</span> <span class="o">{</span>
    <span class="k">if</span><span class="o">(</span><span class="n">name</span><span class="o">.</span><span class="na">contains</span><span class="o">(</span><span class="s">&#34;小&#34;</span><span class="o">))</span> <span class="k">return</span><span class="o">;</span>
    <span class="k">this</span><span class="o">.</span><span class="na">name</span> <span class="o">=</span> <span class="n">name</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div><p>单独给外部开放设置名称的方法，因为我还需要做一些额外的处理，所以说不能给外部直接操作成员变量的权限！</p>
<p>封装思想其实就是把实现细节给隐藏了，外部只需知道这个方法是什么作用，而无需关心实现。</p>
<p>封装就是通过访问权限控制来实现的。</p>
<h3 id="继承">继承</h3>
<p>继承属于非常重要的内容，在定义不同类的时候存在一些相同属性，为了方便使用可以将这些共同属性抽象成一个父类，在定义其他子类时可以继承自该父类，减少代码的重复定义，子类可以使用父类中<strong>非私有</strong>的成员。</p>
<p>现在学生分为两种，艺术生和体育生，他们都是学生的分支，但是他们都有自己的方法：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">SportsStudent</span> <span class="kd">extends</span> <span class="n">Student</span><span class="o">{</span>   <span class="c1">//通过extends关键字来继承父类
</span><span class="c1"></span>
    <span class="kd">public</span> <span class="nf">SportsStudent</span><span class="o">(</span><span class="n">String</span> <span class="n">name</span><span class="o">,</span> <span class="kt">int</span> <span class="n">age</span><span class="o">)</span> <span class="o">{</span>
        <span class="kd">super</span><span class="o">(</span><span class="n">name</span><span class="o">,</span> <span class="n">age</span><span class="o">);</span>   <span class="c1">//必须先通过super关键字（指代父类），实现父类的构造方法！
</span><span class="c1"></span>    <span class="o">}</span>

    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">exercise</span><span class="o">(){</span>
        <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;我超勇的！&#34;</span><span class="o">);</span>
    <span class="o">}</span>
<span class="o">}</span>

<span class="kd">public</span> <span class="kd">class</span> <span class="nc">ArtStudent</span> <span class="kd">extends</span> <span class="n">Student</span><span class="o">{</span>

    <span class="kd">public</span> <span class="nf">ArtStudent</span><span class="o">(</span><span class="n">String</span> <span class="n">name</span><span class="o">,</span> <span class="kt">int</span> <span class="n">age</span><span class="o">)</span> <span class="o">{</span>
        <span class="kd">super</span><span class="o">(</span><span class="n">name</span><span class="o">,</span> <span class="n">age</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">art</span><span class="o">(){</span>
        <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;随手画个毕加索！&#34;</span><span class="o">);</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><p>子类具有父类的全部属性，protected可见但外部无法使用（包括<code>private</code>属性，不可见，无法使用），同时子类还能有自己的方法。继承只能继承一个父类，不支持多继承！</p>
<p>每一个子类必须定义一个实现父类构造方法的构造方法，也就是需要在构造方法开始使用<code>super()</code>，如果父类使用的是默认构造方法，那么子类不用手动指明。</p>
<p>所有类都默认继承自Object类，除非手动指定类型，但是依然改变不了最顶层的父类是Object类。所有类都包含Object类中的方法，比如：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="n">Object</span> <span class="n">obj</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Object</span><span class="o">;</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">obj</span><span class="o">.</span><span class="na">hashCode</span><span class="o">());</span>  <span class="c1">//求对象的hashcode，默认是对象的内存地址
</span><span class="c1"></span><span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">obj</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">obj</span><span class="o">));</span>  <span class="c1">//比较对象是否相同，默认比较的是对象的内存地址，也就是等同于 ==
</span><span class="c1"></span><span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">obj</span><span class="o">.</span><span class="na">toString</span><span class="o">());</span>  <span class="c1">//将对象转换为字符串，默认生成对象的类名称+hashcode
</span><span class="c1"></span><span class="o">}</span>
</code></pre></div><p>关于Object类的其他方法，我们会在Java多线程中再来提及。</p>
<h3 id="多态">多态</h3>
<p>多态是同一个行为具有多个不同表现形式或形态的能力。也就是同样的方法，由于实现类不同，执行的结果也不同！</p>
<h4 id="方法的重写">方法的重写</h4>
<p>我们之前学习了方法的重载，方法的重写和重载是不一样的，重载是原有的方法逻辑不变的情况下，支持更多参数的实现，而重写是直接覆盖原有方法！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="c1">//父类中的study
</span><span class="c1"></span><span class="kd">public</span> <span class="kt">void</span> <span class="nf">study</span><span class="o">(){</span>
    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;学习&#34;</span><span class="o">);</span>
<span class="o">}</span>

<span class="c1">//子类中的study
</span><span class="c1"></span><span class="nd">@Override</span>  <span class="c1">//声明这个方法是重写的，但是可以不要，我们现阶段不接触
</span><span class="c1"></span><span class="kd">public</span> <span class="kt">void</span> <span class="nf">study</span><span class="o">(){</span>
    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;给你看点好康的&#34;</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div><p>再次定义同样的方法后，父类的方法就被覆盖！子类还可以给父类方法提升访问权限！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
     <span class="n">SportsStudent</span> <span class="n">student</span> <span class="o">=</span> <span class="k">new</span> <span class="n">SportsStudent</span><span class="o">(</span><span class="s">&#34;lbw&#34;</span><span class="o">,</span> <span class="n">20</span><span class="o">);</span>
     <span class="n">student</span><span class="o">.</span><span class="na">study</span><span class="o">();</span>   <span class="c1">//输出子类定义的内容
</span><span class="c1"></span><span class="o">}</span>
</code></pre></div><p>思考：静态方法能被重写吗？</p>
<p>当我们在重写方法时，不仅想使用我们自己的逻辑，同时还希望执行父类的逻辑（也就是调用父类的方法）怎么办呢？</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kt">void</span> <span class="nf">study</span><span class="o">(){</span>
    <span class="kd">super</span><span class="o">.</span><span class="na">study</span><span class="o">();</span>
    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;给你看点好康的&#34;</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div><p>同理，如果想访问父类的成员变量，也可以使用super关键字来访问，注意，子类可以具有和父类相同的成员变量！而在方法中访问的默认是 形参列表中 &gt; 当前类的成员变量 &gt; 父类成员变量</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kt">void</span> <span class="nf">setTest</span><span class="o">(</span><span class="kt">int</span> <span class="n">test</span><span class="o">){</span>
    <span class="n">test</span> <span class="o">=</span> <span class="n">1</span><span class="o">;</span>
  	<span class="k">this</span><span class="o">.</span><span class="na">test</span> <span class="o">=</span> <span class="n">1</span><span class="o">;</span>
  	<span class="kd">super</span><span class="o">.</span><span class="na">test</span> <span class="o">=</span> <span class="n">1</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div><h4 id="再谈类型转换">再谈类型转换</h4>
<p>我们曾经学习过基本数据类型的类型转换，支持一种数据类型转换为另一种数据类型，而我们的类也是支持类型转换的（仅限于存在亲缘关系的类之间进行转换）比如子类可以直接向上转型：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="n">Student</span> <span class="n">student</span> <span class="o">=</span> <span class="k">new</span> <span class="n">SportsStudent</span><span class="o">(</span><span class="s">&#34;lbw&#34;</span><span class="o">,</span> <span class="n">20</span><span class="o">);</span>  <span class="c1">//父类变量引用子类实例
</span><span class="c1"></span><span class="n">student</span><span class="o">.</span><span class="na">study</span><span class="o">();</span>     <span class="c1">//得到依然是具体实现的结果，而不是当前类型的结果
</span></code></pre></div><p>我们也可以把已经明确是由哪个类实现的父类引用，强制转换为对应的类型：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="n">Student</span> <span class="n">student</span> <span class="o">=</span> <span class="k">new</span> <span class="n">SportsStudent</span><span class="o">(</span><span class="s">&#34;lbw&#34;</span><span class="o">,</span> <span class="n">20</span><span class="o">);</span>  <span class="c1">//是由SportsStudent进行实现的
</span><span class="c1">//... do something...
</span><span class="c1"></span>
<span class="n">SportsStudent</span> <span class="n">ps</span> <span class="o">=</span> <span class="o">(</span><span class="n">SportsStudent</span><span class="o">)</span><span class="n">student</span><span class="o">;</span>  <span class="c1">//让它变成一个具体的子类
</span><span class="c1"></span><span class="n">ps</span><span class="o">.</span><span class="na">sport</span><span class="o">();</span>  <span class="c1">//调用具体实现类的方法
</span></code></pre></div><p>这样的类型转换称为向下转型。</p>
<h4 id="instanceof关键字">instanceof关键字</h4>
<p>那么我们如果只是得到一个父类引用，但是不知道它到底是哪一个子类的实现怎么办？我们可以使用instanceof关键字来实现，它能够进行类型判断！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">private</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">test</span><span class="o">(</span><span class="n">Student</span> <span class="n">student</span><span class="o">){</span>
    <span class="k">if</span> <span class="o">(</span><span class="n">student</span> <span class="k">instanceof</span> <span class="n">SportsStudent</span><span class="o">){</span>
        <span class="n">SportsStudent</span> <span class="n">sportsStudent</span> <span class="o">=</span> <span class="o">(</span><span class="n">SportsStudent</span><span class="o">)</span> <span class="n">student</span><span class="o">;</span>
        <span class="n">sportsStudent</span><span class="o">.</span><span class="na">sport</span><span class="o">();</span>
    <span class="o">}</span><span class="k">else</span> <span class="k">if</span> <span class="o">(</span><span class="n">student</span> <span class="k">instanceof</span> <span class="n">ArtStudent</span><span class="o">){</span>
        <span class="n">ArtStudent</span> <span class="n">artStudent</span> <span class="o">=</span> <span class="o">(</span><span class="n">ArtStudent</span><span class="o">)</span> <span class="n">student</span><span class="o">;</span>
        <span class="n">artStudent</span><span class="o">.</span><span class="na">art</span><span class="o">();</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><p>通过进行类型判断，我们就可以明确类的具体实现到底是哪个类！</p>
<p>思考：<code>student instanceof Student</code>的结果是什么？</p>
<h4 id="再谈final关键字">再谈final关键字</h4>
<p>我们目前只知道<code>final</code>关键字能够使得一个变量的值不可更改，那么如果在类前面声明final，会发生什么？</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">Student</span> <span class="o">{</span>   <span class="c1">//类被声明为终态，那么它还能被继承吗
</span><span class="c1"></span>  	
<span class="o">}</span>
</code></pre></div><p>类一旦被声明为终态，将无法再被继承，不允许子类的存在！而方法被声明为final呢？</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">final</span> <span class="kt">void</span> <span class="nf">study</span><span class="o">(){</span>  <span class="c1">//还能重写吗
</span><span class="c1"></span>    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;学习&#34;</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div><p>如果类的成员属性被声明为final，那么必须在构造方法中或是在定义时赋初始值！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">private</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">name</span><span class="o">;</span>   <span class="c1">//引用类型不允许再指向其他对象
</span><span class="c1"></span><span class="kd">private</span> <span class="kd">final</span> <span class="kt">int</span> <span class="n">age</span><span class="o">;</span>    <span class="c1">//基本类型值不允许发生改变
</span><span class="c1"></span>
<span class="kd">public</span> <span class="nf">Student</span><span class="o">(</span><span class="n">String</span> <span class="n">name</span><span class="o">,</span> <span class="kt">int</span> <span class="n">age</span><span class="o">)</span> <span class="o">{</span>
    <span class="k">this</span><span class="o">.</span><span class="na">name</span> <span class="o">=</span> <span class="n">name</span><span class="o">;</span>
    <span class="k">this</span><span class="o">.</span><span class="na">age</span> <span class="o">=</span> <span class="n">age</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div><p>学习完封装继承和多态之后，我们推荐在不会再发生改变的成员属性上添加final关键字，JVM会对添加了final关键字的属性进行优化！</p>
<h4 id="抽象类">抽象类</h4>
<p>类本身就是一种抽象，而抽象类，把类还要抽象，也就是说，抽象类可以只保留特征，而不保留具体呈现形态，比如方法可以定义好，但是我可以不去实现它，而是交由子类来进行实现！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">abstract</span> <span class="kd">class</span> <span class="nc">Student</span> <span class="o">{</span>    <span class="c1">//抽象类
</span><span class="c1"></span>		<span class="kd">public</span> <span class="kd">abstract</span> <span class="kt">void</span> <span class="nf">test</span><span class="o">();</span>  <span class="c1">//抽象方法
</span><span class="c1"></span><span class="o">}</span>
</code></pre></div><p>通过使用<code>abstract</code>关键字来表明一个类是一个抽象类，抽象类可以使用<code>abstract</code>关键字来表明一个方法为抽象方法，也可以定义普通方法，抽象方法不需要编写具体实现（无方法体）但是<strong>必须</strong>由子类实现（除非子类也是一个抽象类）！</p>
<p>抽象类由于不是具体的类定义，因此无法直接通过new关键字来创建对象！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="n">Student</span> <span class="n">s</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Student</span><span class="o">(){</span>    <span class="c1">//只能直接创建带实现的匿名内部类！
</span><span class="c1"></span>  <span class="kd">public</span> <span class="kt">void</span> <span class="nf">test</span><span class="o">(){</span>
    
  <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><p>因此，抽象类一般只用作继承使用！抽象类使得继承关系之间更加明确：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kt">void</span> <span class="nf">study</span><span class="o">(){</span>   <span class="c1">//现在只能由子类编写，父类没有定义，更加明确了多态的定义！同一个方法多种实现！
</span><span class="c1"></span>    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;给你看点好康的&#34;</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div><h4 id="接口">接口</h4>
<p>接口甚至比抽象类还抽象，他只代表某个确切的功能！也就是只包含方法的定义，甚至都不是一个类！接口包含了一些列方法的具体定义，类可以实现这个接口，表示类支持接口代表的功能（类似于一个插件，只能作为一个附属功能加在主体上，同时具体实现还需要由主体来实现）</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">Eat</span> <span class="o">{</span>
	<span class="kt">void</span> <span class="nf">eat</span><span class="o">();</span> 
<span class="o">}</span>
</code></pre></div><p>通过使用<code>interface</code>关键字来表明是一个接口（注意，这里class关键字被替换为了interface）接口只能包含<code>public</code>权限的<strong>抽象方法</strong>！（Java8以后可以有默认实现）我们可以通过声明<code>default</code>关键字来给抽象方法一个默认实现：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">Eat</span> <span class="o">{</span>
    <span class="k">default</span> <span class="kt">void</span> <span class="nf">eat</span><span class="o">(){</span>
        <span class="c1">//do something...
</span><span class="c1"></span>    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><p>接口中定义的变量，默认为public static final</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">Eat</span> <span class="o">{</span>
    <span class="kt">int</span> <span class="n">a</span> <span class="o">=</span> <span class="n">1</span><span class="o">;</span>
    <span class="kt">void</span> <span class="nf">eat</span><span class="o">();</span>
<span class="o">}</span>
</code></pre></div><p>一个类可以实现很多个接口，但是不能理解为多继承！（实际上实现接口是附加功能，和继承的概念有一定出入，顶多说是多继承的一种替代方案）一个类可以附加很多个功能！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">SportsStudent</span> <span class="kd">extends</span> <span class="n">Student</span> <span class="kd">implements</span> <span class="n">Eat</span><span class="o">,</span> <span class="o">...{</span>
		<span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">eat</span><span class="o">()</span> <span class="o">{</span>
        
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><p>类通过<code>implements</code>关键字来声明实现的接口！每个接口之间用逗号隔开！</p>
<p>实现接口的类也能通过instanceof关键字判断，也支持向上和向下转型！</p>
<h2 id="内部类">内部类</h2>
<p>类中可以存在一个类！各种各样的长相怪异的代码就是从这里开始出现的！</p>
<h3 id="成员内部类">成员内部类</h3>
<p>我们的类中可以在嵌套一个类：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Test</span> <span class="o">{</span>
    <span class="kd">class</span> <span class="nc">Inner</span><span class="o">{</span>   <span class="c1">//类中定义的一个内部类
</span><span class="c1"></span>        
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><p>成员内部类和成员变量和成员方法一样，都是属于对象的，也就是说，必须存在外部对象，才能创建内部类的对象！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
    <span class="n">Test</span> <span class="n">test</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Test</span><span class="o">();</span>
    <span class="n">Test</span><span class="o">.</span><span class="na">Inner</span> <span class="n">inner</span> <span class="o">=</span> <span class="n">test</span><span class="o">.</span><span class="na">new</span> <span class="nf">Inner</span><span class="o">();</span>   <span class="c1">//写法有那么一丝怪异，但是没毛病！
</span><span class="c1"></span><span class="o">}</span>
</code></pre></div><h3 id="静态内部类">静态内部类</h3>
<p>静态内部类其实就和类中的静态变量和静态方法一样，是属于类拥有的，我们可以直接通过<code>类名.</code>去访问:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Test</span> <span class="o">{</span>
    <span class="kd">static</span> <span class="kd">class</span> <span class="nc">Inner</span><span class="o">{</span>

    <span class="o">}</span>
<span class="o">}</span>

<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
    <span class="n">Test</span><span class="o">.</span><span class="na">Inner</span> <span class="n">inner</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Test</span><span class="o">.</span><span class="na">Inner</span><span class="o">();</span>   <span class="c1">//不用再创建外部类对象了！
</span><span class="c1"></span><span class="o">}</span>
</code></pre></div><h3 id="局部内部类">局部内部类</h3>
<p>对，你没猜错，就是和局部变量一样哒~</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Test</span> <span class="o">{</span>
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">test</span><span class="o">(){</span>
        <span class="kd">class</span> <span class="nc">Inner</span><span class="o">{</span>

        <span class="o">}</span>
        
        <span class="n">Inner</span> <span class="n">inner</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Inner</span><span class="o">();</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><p>反正我是没用过！内部类 -&gt; 累不累 -&gt; 反正我累了！</p>
<h3 id="匿名内部类">匿名内部类</h3>
<p>匿名内部类才是我们的重点，也是实现lambda表达式的原理！匿名内部类其实就是在new的时候，直接对接口或是抽象类的实现：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">Eat</span> <span class="n">eat</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Eat</span><span class="o">()</span> <span class="o">{</span>
            <span class="nd">@Override</span>
            <span class="kd">public</span> <span class="kt">void</span> <span class="nf">eat</span><span class="o">()</span> <span class="o">{</span>
                <span class="c1">//DO something...
</span><span class="c1"></span>            <span class="o">}</span>
        <span class="o">};</span>
    <span class="o">}</span>
</code></pre></div><p>我们不用单独去创建一个类来实现，而是可以直接在new的时候写对应的实现！但是，这样写，无法实现复用，只能在这里使用！</p>
<h4 id="lambda表达式">lambda表达式</h4>
<p>读作<code>λ</code>表达式，它其实就是我们接口匿名实现的简化，比如说：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">Eat</span> <span class="n">eat</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Eat</span><span class="o">()</span> <span class="o">{</span>
            <span class="nd">@Override</span>
            <span class="kd">public</span> <span class="kt">void</span> <span class="nf">eat</span><span class="o">()</span> <span class="o">{</span>
                <span class="c1">//DO something...
</span><span class="c1"></span>            <span class="o">}</span>
        <span class="o">};</span>
    <span class="o">}</span>

<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">Eat</span> <span class="n">eat</span> <span class="o">=</span> <span class="o">()</span> <span class="o">-&gt;</span> <span class="o">{};</span>   <span class="c1">//等价于上述内容
</span><span class="c1"></span>    <span class="o">}</span>
</code></pre></div><p>lambda表达式（匿名内部类）只能访问外部的final类型或是隐式final类型的局部变量！</p>
<p>为了方便，JDK默认就为我们提供了专门写函数式的接口，这里只介绍Consumer</p>
<h2 id="枚举类">枚举类</h2>
<p>假设现在我们想给小明添加一个状态（跑步、学习、睡觉），外部可以实时获取小明的状态：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Student</span> <span class="o">{</span>
    <span class="kd">private</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">name</span><span class="o">;</span>
    <span class="kd">private</span> <span class="kd">final</span> <span class="kt">int</span> <span class="n">age</span><span class="o">;</span>
    <span class="kd">private</span> <span class="n">String</span> <span class="n">status</span><span class="o">;</span>
  
  	<span class="c1">//...
</span><span class="c1"></span>  
  	<span class="kd">public</span> <span class="kt">void</span> <span class="nf">setStatus</span><span class="o">(</span><span class="n">String</span> <span class="n">status</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">status</span> <span class="o">=</span> <span class="n">status</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="n">String</span> <span class="nf">getStatus</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">status</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><p>但是这样会出现一个问题，如果我们仅仅是存储字符串，似乎外部可以不按照我们规则，传入一些其他的字符串。这显然是不够严谨的！</p>
<p>有没有一种办法，能够更好地去实现这样的状态标记呢？我们希望开发者拿到使用的就是我们定义好的状态，我们可以使用枚举类！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">enum</span> <span class="n">Status</span> <span class="o">{</span>
    <span class="n">RUNNING</span><span class="o">,</span> <span class="n">STUDY</span><span class="o">,</span> <span class="n">SLEEP</span>    <span class="c1">//直接写每个状态的名字即可，分号可以不打，但是推荐打上
</span><span class="c1"></span><span class="o">}</span>
</code></pre></div><p>使用枚举类也非常方便，我们只需要直接访问即可</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Student</span> <span class="o">{</span>
    <span class="kd">private</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">name</span><span class="o">;</span>
    <span class="kd">private</span> <span class="kd">final</span> <span class="kt">int</span> <span class="n">age</span><span class="o">;</span>
    <span class="kd">private</span> <span class="n">Status</span> <span class="n">status</span><span class="o">;</span>
  
 		<span class="c1">//...
</span><span class="c1"></span>  
  	<span class="kd">public</span> <span class="kt">void</span> <span class="nf">setStatus</span><span class="o">(</span><span class="n">Status</span> <span class="n">status</span><span class="o">)</span> <span class="o">{</span>   <span class="c1">//不再是String，而是我们指定的枚举类型
</span><span class="c1"></span>        <span class="k">this</span><span class="o">.</span><span class="na">status</span> <span class="o">=</span> <span class="n">status</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="n">Status</span> <span class="nf">getStatus</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">status</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>

<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
    <span class="n">Student</span> <span class="n">student</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Student</span><span class="o">(</span><span class="s">&#34;小明&#34;</span><span class="o">,</span> <span class="n">18</span><span class="o">);</span>
    <span class="n">student</span><span class="o">.</span><span class="na">setStatus</span><span class="o">(</span><span class="n">Status</span><span class="o">.</span><span class="na">RUNNING</span><span class="o">);</span>
    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">student</span><span class="o">.</span><span class="na">getStatus</span><span class="o">());</span>
<span class="o">}</span>
</code></pre></div><p>枚举类型使用起来就非常方便了，其实枚举类型的本质就是一个普通的类，但是它继承自<code>Enum</code>类，我们定义的每一个状态其实就是一个<code>public static final</code>的Status类型成员变量！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="c1">// Compiled from &#34;Status.java&#34;
</span><span class="c1"></span><span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">com</span><span class="o">.</span><span class="na">test</span><span class="o">.</span><span class="na">Status</span> <span class="kd">extends</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">Enum</span><span class="o">&lt;</span><span class="n">com</span><span class="o">.</span><span class="na">test</span><span class="o">.</span><span class="na">Status</span><span class="o">&gt;</span> <span class="o">{</span>
  <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="n">com</span><span class="o">.</span><span class="na">test</span><span class="o">.</span><span class="na">Status</span> <span class="n">RUNNING</span><span class="o">;</span>
  <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="n">com</span><span class="o">.</span><span class="na">test</span><span class="o">.</span><span class="na">Status</span> <span class="n">STUDY</span><span class="o">;</span>
  <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="n">com</span><span class="o">.</span><span class="na">test</span><span class="o">.</span><span class="na">Status</span> <span class="n">SLEEP</span><span class="o">;</span>
  <span class="kd">public</span> <span class="kd">static</span> <span class="n">com</span><span class="o">.</span><span class="na">test</span><span class="o">.</span><span class="na">Status</span><span class="o">[]</span> <span class="nf">values</span><span class="o">();</span>
  <span class="kd">public</span> <span class="kd">static</span> <span class="n">com</span><span class="o">.</span><span class="na">test</span><span class="o">.</span><span class="na">Status</span> <span class="nf">valueOf</span><span class="o">(</span><span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span><span class="o">);</span>
  <span class="kd">static</span> <span class="o">{};</span>
<span class="o">}</span>
</code></pre></div><p>既然枚举类型是普通的类，那么我们也可以给枚举类型添加独有的成员方法</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">enum</span> <span class="n">Status</span> <span class="o">{</span>
    <span class="n">RUNNING</span><span class="o">(</span><span class="s">&#34;睡觉&#34;</span><span class="o">),</span> <span class="n">STUDY</span><span class="o">(</span><span class="s">&#34;学习&#34;</span><span class="o">),</span> <span class="n">SLEEP</span><span class="o">(</span><span class="s">&#34;睡觉&#34;</span><span class="o">);</span>   <span class="c1">//无参构造方法被覆盖，创建枚举需要添加参数（本质就是调用的构造方法！）
</span><span class="c1"></span>
    <span class="kd">private</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">name</span><span class="o">;</span>    <span class="c1">//枚举的成员变量
</span><span class="c1"></span>    <span class="n">Status</span><span class="o">(</span><span class="n">String</span> <span class="n">name</span><span class="o">){</span>    <span class="c1">//覆盖原有构造方法（默认private，只能内部使用！）
</span><span class="c1"></span>        <span class="k">this</span><span class="o">.</span><span class="na">name</span> <span class="o">=</span> <span class="n">name</span><span class="o">;</span>
    <span class="o">}</span>
  
  	<span class="kd">public</span> <span class="n">String</span> <span class="nf">getName</span><span class="o">()</span> <span class="o">{</span>   <span class="c1">//获取封装的成员变量
</span><span class="c1"></span>        <span class="k">return</span> <span class="n">name</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>

<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
    <span class="n">Student</span> <span class="n">student</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Student</span><span class="o">(</span><span class="s">&#34;小明&#34;</span><span class="o">,</span> <span class="n">18</span><span class="o">);</span>
    <span class="n">student</span><span class="o">.</span><span class="na">setStatus</span><span class="o">(</span><span class="n">Status</span><span class="o">.</span><span class="na">RUNNING</span><span class="o">);</span>
    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">student</span><span class="o">.</span><span class="na">getStatus</span><span class="o">().</span><span class="na">getName</span><span class="o">());</span>
<span class="o">}</span>
</code></pre></div><p>枚举类还自带一些继承下来的实用方法</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="n">Status</span><span class="o">.</span><span class="na">valueOf</span><span class="o">(</span><span class="s">&#34;&#34;</span><span class="o">)</span>   <span class="c1">//将名称相同的字符串转换为枚举
</span><span class="c1"></span><span class="n">Status</span><span class="o">.</span><span class="na">values</span><span class="o">()</span>   <span class="c1">//快速获取所有的枚举
</span></code></pre></div><h2 id="基本类型包装类">基本类型包装类</h2>
<p>Java并不是纯面向对象的语言，虽然Java语言是一个面向对象的语言，但是Java中的基本数据类型却不是面向对象的。在学习泛型和集合之前，基本类型的包装类是一定要讲解的内容！</p>
<p>我们的基本类型，如果想通过对象的形式去使用他们，Java提供的基本类型包装类，使得Java能够更好的体现面向对象的思想，同时也使得基本类型能够支持对象操作！</p>
<p><img
        class="lazyload"
        src="/svg/loading.min.svg"
        data-src="https://img2018.cnblogs.com/blog/1504650/201901/1504650-20190122173636211-1359168032.png"
        data-srcset="https://img2018.cnblogs.com/blog/1504650/201901/1504650-20190122173636211-1359168032.png, https://img2018.cnblogs.com/blog/1504650/201901/1504650-20190122173636211-1359168032.png 1.5x, https://img2018.cnblogs.com/blog/1504650/201901/1504650-20190122173636211-1359168032.png 2x"
        data-sizes="auto"
        alt="https://img2018.cnblogs.com/blog/1504650/201901/1504650-20190122173636211-1359168032.png"
        title="img" /></p>
<ul>
<li>byte  -&gt;  Byte</li>
<li>boolean  -&gt;  Boolean</li>
<li>short  -&gt;  Short</li>
<li>char  -&gt;  Character</li>
<li>int -&gt; Integer</li>
<li>long -&gt;  Long</li>
<li>float -&gt; Float</li>
<li>double -&gt; Double</li>
</ul>
<p>包装类实际上就行将我们的基本数据类型，封装成一个类（运用了封装的思想）</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">private</span> <span class="kd">final</span> <span class="kt">int</span> <span class="n">value</span><span class="o">;</span>   <span class="c1">//Integer内部其实本质还是存了一个基本类型的数据，但是我们不能直接操作
</span><span class="c1"></span>
<span class="kd">public</span> <span class="nf">Integer</span><span class="o">(</span><span class="kt">int</span> <span class="n">value</span><span class="o">)</span> <span class="o">{</span>
    <span class="k">this</span><span class="o">.</span><span class="na">value</span> <span class="o">=</span> <span class="n">value</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div><p>现在我们操作的就是Integer对象而不是一个int基本类型了！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
     <span class="n">Integer</span> <span class="n">i</span> <span class="o">=</span> <span class="n">1</span><span class="o">;</span>   <span class="c1">//包装类型可以直接接收对应类型的数据，并变为一个对象！
</span><span class="c1"></span>     <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">i</span> <span class="o">+</span> <span class="n">i</span><span class="o">);</span>    <span class="c1">//包装类型可以直接被当做一个基本类型进行操作！
</span><span class="c1"></span><span class="o">}</span>
</code></pre></div><h4 id="自动装箱和拆箱">自动装箱和拆箱</h4>
<p>那么为什么包装类型能直接使用一个具体值来赋值呢？其实依靠的是自动装箱和拆箱机制</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="n">Integer</span> <span class="n">i</span> <span class="o">=</span> <span class="n">1</span><span class="o">;</span>    <span class="c1">//其实这里只是简写了而已
</span><span class="c1"></span><span class="n">Integer</span> <span class="n">i</span> <span class="o">=</span> <span class="n">Integer</span><span class="o">.</span><span class="na">valueOf</span><span class="o">(</span><span class="n">1</span><span class="o">);</span>  <span class="c1">//编译后真正的样子
</span></code></pre></div><p>调用valueOf来生成一个Integer对象！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="n">Integer</span> <span class="nf">valueOf</span><span class="o">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">)</span> <span class="o">{</span>
    <span class="k">if</span> <span class="o">(</span><span class="n">i</span> <span class="o">&gt;=</span> <span class="n">IntegerCache</span><span class="o">.</span><span class="na">low</span> <span class="o">&amp;&amp;</span> <span class="n">i</span> <span class="o">&lt;=</span> <span class="n">IntegerCache</span><span class="o">.</span><span class="na">high</span><span class="o">)</span>   <span class="c1">//注意，Java为了优化，有一个缓存机制，如果是在-128~127之间的数，会直接使用已经缓存好的对象，而不是再去创建新的！（面试常考）
</span><span class="c1"></span>       <span class="k">return</span> <span class="n">IntegerCache</span><span class="o">.</span><span class="na">cache</span><span class="o">[</span><span class="n">i</span> <span class="o">+</span> <span class="o">(-</span><span class="n">IntegerCache</span><span class="o">.</span><span class="na">low</span><span class="o">)];</span>
  	<span class="k">return</span> <span class="k">new</span> <span class="n">Integer</span><span class="o">(</span><span class="n">i</span><span class="o">);</span>   <span class="c1">//返回一个新创建好的对象
</span><span class="c1"></span><span class="o">}</span>
</code></pre></div><p>而如果使用包装类来进行运算，或是赋值给一个基本类型变量，会进行自动拆箱：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
    <span class="n">Integer</span> <span class="n">i</span> <span class="o">=</span> <span class="n">Integer</span><span class="o">.</span><span class="na">valueOf</span><span class="o">(</span><span class="n">1</span><span class="o">);</span>
    <span class="kt">int</span> <span class="n">a</span> <span class="o">=</span> <span class="n">i</span><span class="o">;</span>    <span class="c1">//简写
</span><span class="c1"></span>    <span class="kt">int</span> <span class="n">a</span> <span class="o">=</span> <span class="n">i</span><span class="o">.</span><span class="na">intValue</span><span class="o">();</span>   <span class="c1">//编译后实际的代码
</span><span class="c1"></span>  
  	<span class="kt">long</span> <span class="n">c</span> <span class="o">=</span> <span class="n">i</span><span class="o">.</span><span class="na">longValue</span><span class="o">();</span>   <span class="c1">//其他类型也有！
</span><span class="c1"></span><span class="o">}</span>
</code></pre></div><p>既然现在是包装类型了，那么我们还能使用<code>==</code>来判断两个数是否相等吗？</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
    <span class="n">Integer</span> <span class="n">i1</span> <span class="o">=</span> <span class="n">28914</span><span class="o">;</span>
    <span class="n">Integer</span> <span class="n">i2</span> <span class="o">=</span> <span class="n">28914</span><span class="o">;</span>

    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">i1</span> <span class="o">==</span> <span class="n">i2</span><span class="o">);</span>   <span class="c1">//实际上判断是两个对象是否为同一个对象（内存地址是否相同）
</span><span class="c1"></span>    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">i1</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">i2</span><span class="o">));</span>   <span class="c1">//这个才是真正的值判断！
</span><span class="c1"></span><span class="o">}</span>
</code></pre></div><p>注意IntegerCache带来的影响！</p>
<p>思考：下面这种情况结果会是什么？</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
    <span class="n">Integer</span> <span class="n">i1</span> <span class="o">=</span> <span class="n">28914</span><span class="o">;</span>
    <span class="n">Integer</span> <span class="n">i2</span> <span class="o">=</span> <span class="n">28914</span><span class="o">;</span>

    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">i1</span><span class="o">+</span><span class="n">1</span> <span class="o">==</span> <span class="n">i2</span><span class="o">+</span><span class="n">1</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div><p>在集合类的学习中，我们还会继续用到我们的包装类型！</p>
<hr>
<h2 id="面向对象编程实战">面向对象编程实战</h2>
<p>虽然我们学习了编程，但是我们不能一股脑的所有问题都照着编程的思维去解决，编程只是解决问题的一种手段，灵活的运用我们所学的知识，才是解决问题的最好办法！比如，求1到100所有数的和：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
    <span class="kt">int</span> <span class="n">sum</span> <span class="o">=</span> <span class="n">0</span><span class="o">;</span>
    <span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">1</span><span class="o">;</span> <span class="n">i</span> <span class="o">&lt;=</span> <span class="n">100</span><span class="o">;</span> <span class="n">i</span><span class="o">++)</span> <span class="o">{</span>   <span class="c1">//for循环暴力求解，简单，但是效率似乎低了一些
</span><span class="c1"></span>        <span class="n">sum</span> <span class="o">+=</span> <span class="n">i</span><span class="o">;</span>
    <span class="o">}</span>
    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">sum</span><span class="o">);</span>
<span class="o">}</span>

<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">((</span><span class="n">1</span> <span class="o">+</span> <span class="n">100</span><span class="o">)</span> <span class="o">*</span> <span class="n">50</span><span class="o">);</span>  <span class="c1">//高斯求和公式，利用数学，瞬间计算结果！
</span><span class="c1"></span><span class="o">}</span>
</code></pre></div><p>说到最后，其实数学和逻辑思维才是解决问题的最终办法！</p>
<h3 id="对象设计面向对象多态运用">对象设计（面向对象、多态运用）</h3>
<ul>
<li>设计一个Person抽象类，包含吃饭运动学习三种行为，分为工人、学生、老师三种职业。</li>
<li>设计设计一个接口<code>考试</code>，只有老师和学生会考试。</li>
<li>设计一个方法，模拟让人类进入考场，要求只有会考试的人才能进入，并且考试。</li>
</ul>
<h3 id="二分搜索搜索算法">二分搜索（搜索算法）</h3>
<p>现在有一个有序数组（从小到大，数组长度 0 &lt; n &lt; 1000000）如何快速寻找我们想要的数在哪个位置，如果存在请返回下标，不存在返回<code>-1</code>即可。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">int</span><span class="o">[]{</span><span class="n">1</span><span class="o">,</span> <span class="n">4</span><span class="o">,</span> <span class="n">5</span><span class="o">,</span> <span class="n">6</span><span class="o">,</span> <span class="n">7</span><span class="o">,</span> <span class="n">10</span><span class="o">,</span> <span class="n">12</span><span class="o">,</span> <span class="n">14</span><span class="o">,</span> <span class="n">20</span><span class="o">,</span> <span class="n">22</span><span class="o">,</span> <span class="n">26</span><span class="o">};</span>   <span class="c1">//测试用例
</span><span class="c1"></span>
<span class="kd">private</span> <span class="kd">static</span> <span class="kt">int</span> <span class="nf">test</span><span class="o">(</span><span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span><span class="o">,</span> <span class="kt">int</span> <span class="n">target</span><span class="o">){</span>
    <span class="c1">//请在这里实现搜索算法
</span><span class="c1"></span><span class="o">}</span>
</code></pre></div><h3 id="快速排序排序算法递归分治">快速排序（排序算法、递归分治）</h3>
<p>（开始之前先介绍一下递归！）快速排序其实是一种排序执行效率很高的排序算法，它利用<strong>分治法</strong>来对待排序序列进行分治排序，它的思想主要是通过一趟排序将待排记录分隔成独立的两部分，其中的一部分比关键字小，后面一部分比关键字大，然后再对这前后的两部分分别采用这种方式进行排序，通过递归的运算最终达到整个序列有序。</p>
<p>快速排序就像它的名字一样，快速！在极端情况下，会退化成冒泡排序！</p>
<h3 id="01背包问题回溯法剪枝动态规划优化">0/1背包问题（回溯法、剪枝/动态规划优化）</h3>
<p>给定 <code>n </code>件物品，每一个物品的重量为 <code>w[n]</code>，每个物品的价值为 <code>v[n]</code>。现挑选物品放入背包中，假定背包能承受的最大重量为 <code>capacity</code>，求装入物品的最大价值是多少?</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kt">int</span><span class="o">[]</span> <span class="n">w</span> <span class="o">=</span> <span class="o">{</span><span class="n">2</span><span class="o">,</span> <span class="n">3</span><span class="o">,</span> <span class="n">4</span><span class="o">,</span> <span class="n">5</span><span class="o">};</span>
<span class="kt">int</span><span class="o">[]</span> <span class="n">v</span> <span class="o">=</span> <span class="o">{</span><span class="n">3</span><span class="o">,</span> <span class="n">4</span><span class="o">,</span> <span class="n">5</span><span class="o">,</span> <span class="n">6</span><span class="o">};</span>
<span class="kt">int</span> <span class="n">capacity</span> <span class="o">=</span> <span class="n">8</span><span class="o">;</span>
</code></pre></div></div><div class="post-footer" id="post-footer">
    <div class="post-info"><div class="post-info-tag"><span><a href="/tags/java%E5%AF%B9%E8%B1%A1%E5%92%8C%E5%A4%9A%E6%80%81/">Java对象和多态</a>
                </span></div><div class="post-info-line"><div class="post-info-mod">
                <span>更新于 2022-01-23</span>
            </div><div class="post-info-mod"></div>
        </div><div class="post-info-share">
            <span><a href="javascript:void(0);" title="分享到 Twitter" data-sharer="twitter" data-url="https://acking-you.github.io/posts/java%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/" data-title="Java对象和多态" data-hashtags="Java对象和多态"><i class="fab fa-twitter fa-fw"></i></a><a href="javascript:void(0);" title="分享到 Facebook" data-sharer="facebook" data-url="https://acking-you.github.io/posts/java%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/" data-hashtag="Java对象和多态"><i class="fab fa-facebook-square fa-fw"></i></a><a href="javascript:void(0);" title="分享到 WhatsApp" data-sharer="whatsapp" data-url="https://acking-you.github.io/posts/java%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/" data-title="Java对象和多态" data-web><i class="fab fa-whatsapp fa-fw"></i></a><a href="javascript:void(0);" title="分享到 Line" data-sharer="line" data-url="https://acking-you.github.io/posts/java%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/" data-title="Java对象和多态"><i class="fab fa-line fa-fw"></i></a><a href="javascript:void(0);" title="分享到 微博" data-sharer="weibo" data-url="https://acking-you.github.io/posts/java%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/" data-title="Java对象和多态" data-image="https://img-blog.csdnimg.cn/img_convert/8db816efd6abe83538c4d47108d9c840.png#pic_center"><i class="fab fa-weibo fa-fw"></i></a><a href="javascript:void(0);" title="分享到 Myspace" data-sharer="myspace" data-url="https://acking-you.github.io/posts/java%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/" data-title="Java对象和多态" data-description="java面向对象"><i data-svg-src="/lib/simple-icons/icons/myspace.min.svg"></i></a><a href="javascript:void(0);" title="分享到 Blogger" data-sharer="blogger" data-url="https://acking-you.github.io/posts/java%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/" data-title="Java对象和多态" data-description="java面向对象"><i class="fab fa-blogger fa-fw"></i></a><a href="javascript:void(0);" title="分享到 Evernote" data-sharer="evernote" data-url="https://acking-you.github.io/posts/java%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/" data-title="Java对象和多态"><i class="fab fa-evernote fa-fw"></i></a></span>
        </div></div><div class="post-nav"><a href="/posts/java%E5%BC%82%E5%B8%B8/" class="prev" rel="prev" title="Java异常处理机制"><i class="fas fa-angle-left fa-fw"></i>Previous Post</a>
            <a href="/posts/java%E5%A4%9A%E7%BA%BF%E7%A8%8B/" class="next" rel="next" title="Java多线程">Next Post<i class="fas fa-angle-right fa-fw"></i></a></div></div>
</div></article></div>
            </main>
            <footer class="footer"><div class="footer-container"><div class="footer-line">由 <a href="https://gohugo.io/" target="_blank" rel="noopener noreffer" title="Hugo 0.86.0">Hugo</a> 强力驱动 | 主题 - <a href="https://github.com/khusika/FeelIt" target="_blank" rel="noopener noreffer" title="FeelIt 1.0.1"><i class="fas fa-hand-holding-heart fa-fw"></i> FeelIt</a>
        </div><div class="footer-line" itemscope itemtype="http://schema.org/CreativeWork"><i class="far fa-copyright fa-fw"></i><span itemprop="copyrightYear">2023</span><span class="author" itemprop="copyrightHolder">&nbsp;<a href="/"></a></span></div>
</div>
</footer>
        </div>

        <div id="fixed-buttons"><a href="#" id="back-to-top" class="fixed-button" title="回到顶部">
                <i class="fas fa-chevron-up fa-fw"></i>
            </a></div><link rel="stylesheet" href="/lib/fontawesome-free/all.min.css"><link rel="stylesheet" href="/lib/animate/animate.min.css"><link rel="stylesheet" href="/lib/katex/katex.min.css"><link rel="stylesheet" href="/lib/katex/copy-tex.min.css"><script src="/lib/autocomplete/autocomplete.min.js"></script><script src="/lib/lunr/lunr.min.js"></script><script src="/lib/lunr/lunr.stemmer.support.min.js"></script><script src="/lib/lunr/lunr.zh.min.js"></script><script src="/lib/lazysizes/lazysizes.min.js"></script><script src="/lib/clipboard/clipboard.min.js"></script><script src="/lib/sharer/sharer.min.js"></script><script src="/lib/katex/katex.min.js"></script><script src="/lib/katex/auto-render.min.js"></script><script src="/lib/katex/copy-tex.min.js"></script><script src="/lib/katex/mhchem.min.js"></script><script>window.config={"code":{"copyTitle":"复制到剪贴板","maxShownLines":200},"comment":{},"math":{"delimiters":[{"display":true,"left":"$$","right":"$$"},{"display":true,"left":"\\[","right":"\\]"},{"display":false,"left":"$","right":"$"},{"display":false,"left":"\\(","right":"\\)"}],"strict":false},"search":{"highlightTag":"em","lunrIndexURL":"/index.json","lunrLanguageCode":"zh","lunrSegmentitURL":"/lib/lunr/lunr.segmentit.js","maxResultLength":100,"noResultsFound":"没有找到结果","snippetLength":50,"type":"lunr"}};</script><script src="/js/theme.min.js"></script></body></html>
